package com.mcp.converter.domain.parser.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mcp.converter.domain.parser.*;
import com.mcp.converter.shared.enums.SQLType;
import com.mcp.converter.domain.rule.manager.RuleManager;
import com.mcp.converter.shared.response.analysis.BatchAnalysisResponse;
import com.mcp.converter.shared.response.analysis.CompatibilityReclassificationResult;
import com.mcp.converter.shared.response.analysis.FallbackCompatibilityResult;
import com.mcp.converter.shared.response.xml.XMLParseResult;
import com.mcp.converter.shared.response.sql.SQLLocation;
import com.mcp.converter.shared.response.sql.SQLParseResult;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * Mybatis XML文件解析器接口
 * 用于解析Mybatis XML文件并提取其中的SQL语句
 * @author zengxiong
 */
@Component
public class MybatisXMLParserImpl implements MybatisXMLParser {
    private static final Logger logger = LoggerFactory.getLogger(MybatisXMLParserImpl.class);
    
    private static final List<String> SQL_ELEMENTS = Arrays.asList(
            "select", "insert", "update", "delete", "sql"
    );
    
    private final ObjectMapper objectMapper;
    private final RuleManager ruleManager;
    private final SQLParser sqlParser;
    private final Map<String, String> sqlFragmentCache = new HashMap<>();

    public MybatisXMLParserImpl(RuleManager ruleManager, SQLParser sqlParser) {
        this.objectMapper = new ObjectMapper();
        this.ruleManager = ruleManager;
        this.sqlParser = sqlParser;
    }

    @Override
    public List<SQLLocation> extractSQLStatements(String xmlPath) {
        try {
            Document document = new SAXReader().read(new File(xmlPath));
            return extractSQLStatementsFromDocument(document, xmlPath);
        } catch (DocumentException e) {
            logger.error("Failed to parse XML file: {}", xmlPath, e);
            // 返回空列表而不是抛出异常，让调用方继续处理
            return new ArrayList<>();
        }
    }

    private List<SQLLocation> extractSQLStatementsFromDocument(Document document, String xmlPath) {
        List<SQLLocation> sqlLocations = new ArrayList<>();
        
        try {
            Element rootElement = document.getRootElement();
            sqlLocations.addAll(extractFromMyBatisFormat(rootElement, xmlPath));
        } catch (Exception e) {
            logger.error("Failed to extract SQL statements from document: {}", xmlPath, e);
            // 返回空列表而不是抛出异常，让调用方继续处理
            return new ArrayList<>();
        }
        
        return sqlLocations;
    }
    
    /**
     * 从MyBatis格式XML中提取SQL语句
     */
    private List<SQLLocation> extractFromMyBatisFormat(Element rootElement, String xmlPath) {
        List<SQLLocation> sqlLocations = new ArrayList<>();
        
        for (String elementType : SQL_ELEMENTS) {
            List<Element> elements = rootElement.elements(elementType);
            for (Element element : elements) {
                SQLLocation location = createSQLLocationFromElement(element, elementType, xmlPath);
                sqlLocations.add(location);
            }
        }
        
        return sqlLocations;
    }
    
    /**
     * 从XML元素创建SQLLocation对象
     */
    private SQLLocation createSQLLocationFromElement(Element element, String elementType, String xmlPath) {
        SQLLocation location = new SQLLocation();
        location.setXmlPath(xmlPath);
        location.setSqlId(element.attributeValue("id"));
        // 使用getText()而不是getTextTrim()来保留CDATA内容
        String sqlContent = element.getText();
        if (sqlContent != null) {
            sqlContent = sqlContent.trim();
            // 处理动态标签，包括<isNotEmpty>标签
            sqlContent = processCommonDynamicTags(sqlContent);
        }
        location.setSqlContent(sqlContent);
        location.setElementType(elementType);
        location.setSqlType(getSQLType(elementType));
        
        // 获取行号信息
        String lineNumber = element.attributeValue("lineNumber");
        if (lineNumber != null) {
            location.setStartLine(Integer.parseInt(lineNumber));
            // 简单估算结束行号，实际实现可能需要更复杂的逻辑
            String content = sqlContent != null ? sqlContent : "";
            location.setEndLine(Integer.parseInt(lineNumber) + content.split("\n").length);
        }
        
        return location;
    }
    
    public SQLType getSQLType(String elementType) {
        if (elementType == null) {
            return SQLType.UNKNOWN;
        }

        switch (elementType.toLowerCase()) {
            case "select":
                return SQLType.SELECT;
            case "insert":
                return SQLType.INSERT;
            case "update":
                return SQLType.UPDATE;
            case "delete":
                return SQLType.DELETE;
            case "sql":
                // SQL片段
                return SQLType.UNKNOWN;
            default:
                return SQLType.UNKNOWN;
        }
    }

    @Override
    public XMLParseResult parseFileContent(String xmlContent, String virtualPath) {
        XMLParseResult result = XMLParseResult.forMyBatis(virtualPath);
        result.setXmlPath(virtualPath);
        try {
            org.dom4j.Element rootElement = parseAndValidateXmlContent(xmlContent);
            result.setNamespace(rootElement.attributeValue("namespace"));
            result.setSqlLocations(createSqlLocations(rootElement, virtualPath));
            result.setParseSuccess(true);
        } catch (IllegalArgumentException e) {
            result.setParseSuccess(false);
            result.setErrorMessage(e.getMessage());
        } catch (org.dom4j.DocumentException e) {
            logger.error("XML结构错误: {}，文件: {}，尝试自动修复...", e.getMessage(), virtualPath, e);
            // 尝试自动修复XML内容
            result = tryAutoFixXmlContent(xmlContent, virtualPath, e);
        } catch (Exception e) {
            logger.error("Unexpected error parsing XML content: {}", virtualPath, e);
            result.setParseSuccess(false);
            result.setErrorMessage("未知错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 尝试自动修复XML内容
     */
    private XMLParseResult tryAutoFixXmlContent(String xmlContent, String virtualPath, org.dom4j.DocumentException originalException) {
        XMLParseResult result = XMLParseResult.forMyBatis(virtualPath);
        result.setXmlPath(virtualPath);
        
        // 自动修复尝试：先清理无效字符，然后补全未闭合的根标签
        String cleanedContent = cleanInvalidXmlCharacters(xmlContent);
        String fixedContent = tryFixXmlContent(cleanedContent);
        
        if (!fixedContent.equals(xmlContent)) {
            try {
                org.dom4j.Element rootElement = parseAndValidateXmlContent(fixedContent);
                result.setNamespace(rootElement.attributeValue("namespace"));
                result.setSqlLocations(createSqlLocations(rootElement, virtualPath));
                result.setParseSuccess(true);
                logger.info("自动修复XML结构成功: {}", virtualPath);
            } catch (Exception fixEx) {
                logger.error("自动修复XML结构失败: {}，文件: {}", fixEx.getMessage(), virtualPath, fixEx);
                result.setParseSuccess(false);
                result.setErrorMessage("XML结构错误: " + originalException.getMessage() + 
                    "。自动修复尝试失败: " + fixEx.getMessage() + "。请检查XML标签属性是否重复、缺失或格式错误。");
            }
        } else {
            result.setParseSuccess(false);
            result.setErrorMessage("XML结构错误: " + originalException.getMessage() + "。请检查XML标签属性是否重复、缺失或格式错误。");
        }
        
        return result;
    }

    /**
     * 解析和验证XML内容
     */
    private Element parseAndValidateXmlContent(String xmlContent) throws DocumentException {
        // 清理XML内容中的无效字符
        String cleanedXmlContent = cleanInvalidXmlCharacters(xmlContent);
        
        // 通过字符串解析XML内容
        SAXReader reader = new SAXReader();
        StringReader stringReader = new StringReader(cleanedXmlContent);
        Document document = reader.read(stringReader);
        Element rootElement = document.getRootElement();

        // 验证是否为有效的Mybatis映射文件
        String rootElementName = rootElement.getName();
        if (!"mapper".equals(rootElementName)) {
            throw new IllegalArgumentException("不是有效的Mybatis映射文件，根元素不是'mapper'，当前根元素: " + rootElementName);
        }

        return rootElement;
    }

    /**
     * 创建SQL位置列表
     */
    private List<SQLLocation> createSqlLocations(org.dom4j.Element rootElement, String xmlPath) {
        // 先构建SQL片段缓存
        buildSqlFragmentCache(rootElement);
        
        List<SQLLocation> sqlLocations = new ArrayList<>();
        for (String elementType : SQL_ELEMENTS) {
            List<org.dom4j.Element> elements = rootElement.elements(elementType);
            for (org.dom4j.Element element : elements) {
                SQLLocation location = createSqlLocation(element, elementType, xmlPath);
                sqlLocations.add(location);
            }
        }
        return sqlLocations;
    }

    /**
     * 创建单个SQL位置对象
     */
    private SQLLocation createSqlLocation(org.dom4j.Element element, String elementType, String xmlPath) {
        SQLLocation location = new SQLLocation();
        location.setXmlPath(xmlPath);
        location.setSqlId(element.attributeValue("id"));
        // 使用getText()而不是getTextTrim()来保留CDATA内容
        String sqlContent = element.getText();
        if (sqlContent != null) {
            sqlContent = sqlContent.trim();
        }
        location.setSqlContent(sqlContent);
        location.setElementType(elementType);
        location.setSqlType(getSQLType(elementType));

        // 获取行号信息
        String lineNumber = element.attributeValue("lineNumber");
        if (lineNumber != null) {
            location.setStartLine(Integer.parseInt(lineNumber));
            String content = sqlContent != null ? sqlContent : "";
            location.setEndLine(Integer.parseInt(lineNumber) + content.split("\n").length);
        }

        return location;
    }

    /**
     * 清理XML内容中的无效字符和常见问题
     * 根据XML标准，只保留以下字符：
     * - 0x09 (tab), 0x0A (line feed), 0x0D (carriage return)
     * - 0x20-0xD7FF, 0xE000-0xFFFD, 0x10000-0x10FFFF
     * 同时修复常见的XML结构问题
     */
    private String cleanInvalidXmlCharacters(String xmlContent) {
        if (xmlContent == null) {
            return "";
        }
        
        StringBuilder cleanedContent = new StringBuilder();
        for (int i = 0; i < xmlContent.length(); i++) {
            char c = xmlContent.charAt(i);
            if (isValidXmlChar(c)) {
                cleanedContent.append(c);
            } else {
                // 记录被清理的字符
                logger.debug("清理无效XML字符: 0x{}", Integer.toHexString(c));
            }
        }
        
        String cleaned = cleanedContent.toString();
        
        // 清理文件末尾的多余字符
        cleaned = cleaned.replaceAll("[%\\x00-\\x1F]*$", "");
        
        // 确保以</mapper>结尾
        cleaned = cleaned.trim();
        if (!cleaned.endsWith("</mapper>")) {
            // 查找最后一个</mapper>位置
            int lastMapperEnd = cleaned.lastIndexOf("</mapper>");
            if (lastMapperEnd > 0) {
                cleaned = cleaned.substring(0, lastMapperEnd + 9);
            }
        }
        
        return cleaned;
    }
    
    /**
     * 检查字符是否为有效的XML字符
     */
    private boolean isValidXmlChar(char c) {
        return (c == 0x09) || 
               (c == 0x0A) || 
               (c == 0x0D) || 
               (c >= 0x20 && c <= 0xD7FF) || 
               (c >= 0xE000 && c <= 0xFFFD);
    }

    /**
     * 尝试修复常见的XML结构错误，如未闭合的根标签、文件截断等
     */
    private String tryFixXmlContent(String xmlContent) {
        if (xmlContent == null) {
            return "";
        }
        String content = xmlContent.trim();
        // 检查是否以</mapper>结尾，否则补全
        if (!content.endsWith("</mapper>")) {
            int lastMapperClose = content.lastIndexOf("</mapper>");
            if (lastMapperClose == -1) {
                // 没有闭合标签，直接补全
                content = content + "\n</mapper>";
            }
        }
        // 只保留到最后一个>，去除后面多余内容
        int lastGt = content.lastIndexOf('>');
        if (lastGt > 0 && lastGt < content.length() - 1) {
            content = content.substring(0, lastGt + 1);
        }
        return content;
    }
    

    @Override
    public FallbackCompatibilityResult performFallbackCompatibilityCheck(List<String> validSqls, BatchAnalysisResponse batchResult) {
        FallbackCompatibilityResult result = new FallbackCompatibilityResult();
        
        if (validSqls == null || validSqls.isEmpty()) {
            logger.debug("没有有效的SQL语句需要进行后备兼容性检查");
            return result;
        }
        
        logger.debug("开始进行Mybatis后备兼容性检查，SQL数量: {}", validSqls.size());
        
        // 使用RuleManager检查不兼容函数，而不是硬编码
        for (int i = 0; i < validSqls.size(); i++) {
            String sql = validSqls.get(i);
            if (sql == null || sql.trim().isEmpty()) {
                continue;
            }
            
            // 使用containsIncompatibleFunctions方法，该方法已经依赖RuleManager
            if (containsIncompatibleFunctions(sql)) {
                result.getIncompatibleSqlIndexes().add(i);
                
                // 找出具体的不兼容函数
                Set<String> incompatibleFunctions = ruleManager.getAllIncompatibleFunctions();
                for (String function : incompatibleFunctions) {
                    String pattern = "\\b" + function + "\\s*\\(";
                    java.util.regex.Pattern compiledPattern = java.util.regex.Pattern.compile(pattern, java.util.regex.Pattern.CASE_INSENSITIVE);
                    if (compiledPattern.matcher(sql).find()) {
                        result.getFunctionDetails().put(String.valueOf(i), "包含不兼容函数: " + function + " - 请参考兼容性规则进行替代");
                        break;
                    }
                }
            }
        }
        
        logger.debug("Mybatis后备兼容性检查完成，发现不兼容SQL数量: {}", result.getIncompatibleSqlIndexes().size());
        return result;
    }

    @Override
    public String readXmlFileContent(String xmlFilePath) {
        try {
            Path path = Paths.get(xmlFilePath);
            
            // 检查文件是否存在
            if (!Files.exists(path)) {
                logger.error("XML文件不存在: {}", xmlFilePath);
                return null;
            }
            
            // 检查是否为文件
            if (!Files.isRegularFile(path)) {
                logger.error("指定路径不是文件: {}", xmlFilePath);
                return null;
            }
            
            // 读取文件内容
            byte[] bytes = Files.readAllBytes(path);
            String content = new String(bytes, StandardCharsets.UTF_8);
            
            logger.debug("成功读取XML文件: {}, 大小: {} bytes", xmlFilePath, bytes.length);
            return content;
            
        } catch (java.io.IOException e) {
            logger.error("读取XML文件失败: {}, 错误: {}", xmlFilePath, e.getMessage(), e);
            return null;
        } catch (Exception e) {
            logger.error("读取XML文件时发生未知错误: {}, 错误: {}", xmlFilePath, e.getMessage(), e);
            return null;
        }
    }

    @Override
    public boolean containsIncompatibleFunctions(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return false;
        }

        // 使用RuleManager获取不兼容函数列表
        Set<String> incompatibleFunctions = ruleManager.getAllIncompatibleFunctions();

        for (String function : incompatibleFunctions) {
            // 使用函数调用模式匹配，避免误报
            String pattern = "\\b" + function + "\\s*\\(";
            java.util.regex.Pattern compiledPattern = java.util.regex.Pattern.compile(pattern, java.util.regex.Pattern.CASE_INSENSITIVE);
            java.util.regex.Matcher matcher = compiledPattern.matcher(sql);

            if (matcher.find()) {
                logger.debug("在SQL中检测到不兼容函数: {}", function);
                return true;
            }
        }
        return false;
    }
    
    @Override
    /**
     * 执行智能重分类 - 严格按照 SQL提取 → JSqlParser语法校验 → RuleManager兼容性校验 流程
     */
    public CompatibilityReclassificationResult performIntelligentReclassification(BatchAnalysisResponse batchResult,
                                                                                  List<String> validSqls) {

        int originalErrorCount = batchResult.getErrorCount();
        int correctedIncompatibleCount = batchResult.getIncompatibleCount();
        int correctedErrorCount = originalErrorCount;

        logger.debug("开始智能错误重分类 - 原始统计: 兼容={}, 不兼容={}, 错误={}",
                 batchResult.getCompatibleCount(), correctedIncompatibleCount, originalErrorCount);

        // 针对每个有效SQL进行标准化的三步分析流程
        if (!validSqls.isEmpty() && batchResult.getErrors() != null && !batchResult.getErrors().isEmpty()) {
            for (int i = 0; i < validSqls.size(); i++) {
                String sql = validSqls.get(i);

                // 检查此SQL是否在错误列表中
                boolean isMarkedAsError = batchResult.getErrors().containsKey(i) || batchResult.getErrors().containsKey(i + 1);

                if (isMarkedAsError) {
                    // 执行标准化的三步分析流程
                    AnalysisResult analysisResult = performStandardizedAnalysis(sql, i);
                    
                    switch (analysisResult.getStatus()) {
                        case COMPATIBLE:
                            correctedErrorCount--;
                            logger.debug("SQL[{}] 重新分类：错误 → 兼容 (通过标准化分析)", i);
                            break;
                        case INCOMPATIBLE:
                            correctedIncompatibleCount++;
                            correctedErrorCount--;
                            logger.debug("SQL[{}] 重新分类：错误 → 不兼容 (通过标准化分析)", i);
                            break;
                        case ERROR:
                            // 保持错误状态
                            logger.debug("SQL[{}] 保持错误状态 (标准化分析失败)", i);
                            break;
                    }
                }
            }
        }

        // 确保错误计数不为负数
        if (correctedErrorCount < 0) {
            correctedErrorCount = 0;
        }

        logger.debug("智能重分类完成 - 修正后统计: 兼容={}, 不兼容={}, 错误={}",
                 batchResult.getCompatibleCount(), correctedIncompatibleCount, correctedErrorCount);

        return new CompatibilityReclassificationResult(
            originalErrorCount, correctedIncompatibleCount, correctedErrorCount);
    }
    
    /**
     * 执行标准化的三步分析流程：SQL提取 → JSqlParser语法校验 → RuleManager兼容性校验
     */
    private AnalysisResult performStandardizedAnalysis(String sql, int index) {
        logger.debug("开始对SQL[{}]执行标准化三步分析流程", index);
        
        try {
            // 第一步：SQL提取和清理（已经完成，这里是提取后的SQL）
            String cleanedSql = sql;
            if (cleanedSql == null || cleanedSql.trim().isEmpty()) {
                return new AnalysisResult(AnalysisStatus.ERROR, "SQL为空");
            }
            
            // 第二步：JSqlParser语法校验
            boolean syntaxValid = performJSqlParserValidation(cleanedSql);
            if (!syntaxValid) {
                logger.debug("SQL[{}] JSqlParser语法校验失败，检查是否为有效的SQL结构", index);
                
                // 如果JSqlParser校验失败，但SQL具有有效结构，继续进行兼容性校验
                if (!isValidSqlStructure(cleanedSql)) {
                    return new AnalysisResult(AnalysisStatus.ERROR, "SQL语法无效且结构不完整");
                }
                
                logger.debug("SQL[{}] 虽然JSqlParser校验失败，但具有有效SQL结构，继续兼容性校验", index);
            }
            
            // 第三步：RuleManager兼容性校验
            boolean hasIncompatibleElements = performRuleManagerCompatibilityCheck(cleanedSql);
            if (hasIncompatibleElements) {
                return new AnalysisResult(AnalysisStatus.INCOMPATIBLE, "包含不兼容的函数或语法");
            }
            
            // 如果通过所有检查，则认为是兼容的
            return new AnalysisResult(AnalysisStatus.COMPATIBLE, "通过所有兼容性检查");
            
        } catch (Exception e) {
            logger.error("标准化分析过程中发生异常: {}", e.getMessage(), e);
            return new AnalysisResult(AnalysisStatus.ERROR, "分析过程异常: " + e.getMessage());
        }
    }
    
    /**
     * 执行JSqlParser语法校验
     */
    private boolean performJSqlParserValidation(String sql) {
        try {
            // 使用SQLParser进行语法校验
            SQLParseResult parseResult = sqlParser.parse(sql);
            
            // 检查解析是否成功
            if (parseResult == null || parseResult.getElements().isEmpty()) {
                logger.debug("JSqlParser解析失败：解析结果为空");
                return false;
            }
            
            // 检查是否有解析失败的标记
            Object parseFailure = parseResult.getAttribute("parseFailure");
            if (parseFailure != null && (Boolean) parseFailure) {
                logger.debug("JSqlParser解析失败：存在解析失败标记");
                return false;
            }
            
            logger.debug("JSqlParser语法校验通过");
            return true;
            
        } catch (Exception e) {
            logger.debug("JSqlParser语法校验异常: {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 执行RuleManager兼容性校验
     */
    private boolean performRuleManagerCompatibilityCheck(String sql) {
        try {
            // 使用RuleManager检查不兼容函数
            boolean hasIncompatibleFunctions = containsIncompatibleFunctions(sql);
            if (hasIncompatibleFunctions) {
                String foundFunction = findFirstIncompatibleFunction(sql);
                logger.debug("RuleManager兼容性校验：发现不兼容函数 {}", foundFunction);
                return true;
            }
            
            // 可以在这里添加更多的RuleManager规则检查
            // 例如：不兼容的数据类型、语法结构等
            
            logger.debug("RuleManager兼容性校验：未发现不兼容元素");
            return false;
            
        } catch (Exception e) {
            logger.error("RuleManager兼容性校验异常: {}", e.getMessage(), e);
            // 异常情况下，保守地认为可能存在不兼容问题
            return true;
        }
    }
    
    /**
     * 检查SQL是否具有有效的结构
     */
    private boolean isValidSqlStructure(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return false;
        }
        
        String upperSql = sql.trim().toUpperCase();
        
        // 检查是否包含基本的SQL关键字结构
        boolean hasValidStructure = false;
        
        // SELECT语句结构检查
        if (upperSql.startsWith("SELECT") && upperSql.contains("FROM")) {
            hasValidStructure = true;
        }
        // INSERT语句结构检查
        else if (upperSql.startsWith("INSERT") && upperSql.contains("INTO")) {
            hasValidStructure = true;
        }
        // UPDATE语句结构检查
        else if (upperSql.startsWith("UPDATE") && upperSql.contains("SET")) {
            hasValidStructure = true;
        }
        // DELETE语句结构检查
        else if (upperSql.startsWith("DELETE") && upperSql.contains("FROM")) {
            hasValidStructure = true;
        }
        
        return hasValidStructure;
    }
    
    /**
     * 找出SQL中第一个不兼容函数
     */
    private String findFirstIncompatibleFunction(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return null;
        }

        // 使用RuleManager获取不兼容函数列表
        Set<String> incompatibleFunctions = ruleManager.getAllIncompatibleFunctions();

        for (String function : incompatibleFunctions) {
            // 使用函数调用模式匹配，避免误报
            String pattern = "\\b" + function + "\\s*\\(";
            java.util.regex.Pattern compiledPattern = java.util.regex.Pattern.compile(pattern, java.util.regex.Pattern.CASE_INSENSITIVE);
            java.util.regex.Matcher matcher = compiledPattern.matcher(sql);

            if (matcher.find()) {
                return function;
            }
        }
        return null;
    }
    
    /**
     * 分析结果枚举
     */
    private enum AnalysisStatus {
        COMPATIBLE,    // 兼容
        INCOMPATIBLE,  // 不兼容
        ERROR          // 错误
    }
    
    /**
     * 分析结果类
     */
    private static class AnalysisResult {
        private final AnalysisStatus status;
        private final String message;
        
        public AnalysisResult(AnalysisStatus status, String message) {
            this.status = status;
            this.message = message;
        }
        
        public AnalysisStatus getStatus() {
            return status;
        }
        
        public String getMessage() {
            return message;
        }
    }

    @Override
    public String extractFileNameFromPath(String filePath) {
        if (filePath == null || filePath.isEmpty()) {
            return "unknown_file";
        }
        
        try {
            Path path = Paths.get(filePath);
            Path fileName = path.getFileName();
            return fileName != null ? fileName.toString() : "unknown_file";
        } catch (Exception e) {
            // 如果路径解析失败，使用简单的字符串处理
            int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
            return lastSeparator >= 0 ? filePath.substring(lastSeparator + 1) : filePath;
        }
    }
    
    @Override
    public String preprocessXmlContent(String xmlContent) {
        if (xmlContent == null) {
            return "";
        }
        
        try {
            String processed = xmlContent;
            
            // 去除<resultMap>标签及其内容
            processed = processed.replaceAll("(?s)<resultMap[^>]*?>.*?</resultMap>", "");
            
            // 去除注释
            processed = processed.replaceAll("(?s)<!--.*?-->", "");
            
            // 处理CDATA块中的中文标点符号
            processed = processCdataBlocks(processed);
            
            logger.debug("XML预处理完成，去除了resultMap和注释，并处理了CDATA块");
            return processed;
            
        } catch (Exception e) {
            logger.warn("XML预处理失败，使用原始内容: {}", e.getMessage());
            return xmlContent;
        }
    }
    
    /**
     * 处理CDATA块中的中文标点符号和特殊字符
     */
    private String processCdataBlocks(String xmlContent) {
        if (xmlContent == null) {
            return "";
        }
        
        // 使用正则表达式匹配CDATA块
        Pattern cdataPattern = Pattern.compile("<!\\[CDATA\\[(.*?)\\]\\]>", Pattern.DOTALL);
        Matcher matcher = cdataPattern.matcher(xmlContent);
        
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            String cdataContent = matcher.group(1);
            
            // 处理中文标点符号
            cdataContent = cdataContent.replace("，", ",")  // 中文逗号转英文逗号
                                     .replace("；", ";")  // 中文分号转英文分号
                                     .replace("：", ":")  // 中文冒号转英文冒号
                                     .replace("（", "(")  // 中文左括号转英文左括号
                                     .replace("）", ")")  // 中文右括号转英文右括号
                                     .replace("'", "'")  // 中文单引号转英文单引号
                                     .replace("'", "'")  // 中文单引号转英文单引号
                                     .replace("\"", "\"") // 中文双引号转英文双引号
                                     .replace("\"", "\""); // 中文双引号转英文双引号
            
            // 重新构建CDATA块
            matcher.appendReplacement(result, "<![CDATA[" + cdataContent + "]]>");
        }
        matcher.appendTail(result);
        
        return result.toString();
    }
    
    @Override
    public boolean isSQLComplete(String sqlContent) {
        if (sqlContent == null || sqlContent.trim().isEmpty()) {
            return false;
        }
        
        String trimmed = sqlContent.trim();
        
        // 处理CDATA包裹的SQL内容
        if (trimmed.startsWith("<![CDATA[") && trimmed.endsWith("]]")) {
            trimmed = trimmed.substring(9, trimmed.length() - 2).trim();
        }
        
        // 检查是否只包含中文字符或特殊字符，如果是则认为不完整
        if (trimmed.matches("^[\u4e00-\u9fa5\s]*$") || trimmed.matches("^[^a-zA-Z0-9]*$")) {
            return false;
        }
        
        // 检查是否只是SQL片段标识符（如replyWhere1等）
        if (trimmed.matches("^\\w+\\d*$")) {
            return false;
        }
        
        trimmed = trimmed.toLowerCase();
        
        // 扩展SQL关键字检查
        boolean hasKeyword = trimmed.startsWith("select") || 
                           trimmed.startsWith("insert") || 
                           trimmed.startsWith("update") || 
                           trimmed.startsWith("delete") ||
                           trimmed.startsWith("with") ||
                           trimmed.startsWith("create") ||
                           trimmed.startsWith("drop") ||
                           trimmed.startsWith("alter") ||
                           trimmed.startsWith("(select") ||
                           trimmed.contains(" select ") ||
                           trimmed.contains(" insert ") ||
                           trimmed.contains(" update ") ||
                           trimmed.contains(" delete ") ||
                           trimmed.contains(" from ") ||
                           trimmed.contains(" where ") ||
                           trimmed.contains(" set ");
        
        if (!hasKeyword) {
            return false;
        }
        
        // 检查SQL语句的基本结构完整性
        if (trimmed.startsWith("select")) {
            // SELECT语句必须包含FROM或者是子查询
            return trimmed.contains(" from ") || trimmed.contains("(") || trimmed.contains("union");
        } else if (trimmed.startsWith("insert")) {
            // INSERT语句必须包含INTO和VALUES或SELECT
            // 特殊处理：如果是insert语句，只要包含into和values关键字就认为是完整的，即使values后面是空参数
            boolean hasInto = trimmed.contains(" into ") || trimmed.contains("into ");
            boolean hasValues = trimmed.contains(" values") || trimmed.contains("values");
            boolean hasSelect = trimmed.contains(" select ") || trimmed.contains("select ");
            if (hasInto) {
                if (hasValues) {
                    return true;
                } else if (hasSelect) {
                    return true;
                }
            }
            return false;
        } else if (trimmed.startsWith("update")) {
            // UPDATE语句必须包含SET
            return trimmed.contains(" set ");
        } else if (trimmed.startsWith("delete")) {
            // DELETE语句必须包含FROM
            return trimmed.contains(" from ");
        }
        
        // 检查是否包含未处理的MyBatis标签（更严格的检查）
        if (sqlContent.contains("<") && sqlContent.contains(">")) {
            // 检查是否包含实际的XML标签而不只是比较运算符
            if (sqlContent.matches(".*<\\s*[a-zA-Z/].*") || 
                sqlContent.contains("<if") || 
                sqlContent.contains("<set") || 
                sqlContent.contains("<trim") || 
                sqlContent.contains("<where") || 
                sqlContent.contains("<dynamic") || 
                sqlContent.contains("<include") ||
                sqlContent.contains("<isNotEmpty") ||
                sqlContent.contains("<isEmpty") ||
                sqlContent.contains("<isNotNull") ||
                sqlContent.contains("<isNull")) {
                return false;
            }
        }
        
        // 检查是否只包含动态SQL片段（没有实际SQL语句）
        String cleanedForCheck = trimmed.replaceAll("<[^>]*>", "").trim();
        if (cleanedForCheck.isEmpty() || cleanedForCheck.matches("^[\\s\\r\\n]*$")) {
            return false;
        }
        
        // 检查是否只包含条件表达式而没有完整的SQL结构
        // 例如：只有 "AND TIME >= to_date('','yyyy-MM-dd hh24:mi:ss')" 这样的片段
        if (cleanedForCheck.matches("^\\s*(and|or)\\s+.*") && !cleanedForCheck.contains("select") && 
            !cleanedForCheck.contains("insert") && !cleanedForCheck.contains("update") && !cleanedForCheck.contains("delete")) {
            return false;
        }
        
        // 检查是否只包含SET子句片段
        if (cleanedForCheck.matches("^\\s*set\\s+.*") && !cleanedForCheck.contains("update")) {
            return false;
        }
        
        // 检查CDATA标签内的SQL是否完整
        if (trimmed.contains("<![CDATA[") && trimmed.contains("]]>")) {
            String cdataContent = trimmed.replaceAll(".*<!\\[CDATA\\[(.*?)\\]\\]>.*", "$1").trim();
            if (cdataContent.isEmpty()) {
                return false;
            }
            // 对于CDATA内容，检查是否包含基本的SQL关键字和WHERE子句
            String lowerCdata = cdataContent.toLowerCase();
            if ((lowerCdata.contains("update") && lowerCdata.contains("set") && lowerCdata.contains("where")) ||
                (lowerCdata.contains("select") && lowerCdata.contains("from")) ||
                (lowerCdata.contains("insert") && lowerCdata.contains("into")) ||
                (lowerCdata.contains("delete") && lowerCdata.contains("from"))) {
                // 如果包含完整的SQL结构，则认为是完整的
                return true;
            }
        }
        
        // 检查是否只包含动态标签而没有实际SQL内容
        String withoutTags = trimmed.replaceAll("<[^>]+>", "").trim();
        if (withoutTags.isEmpty() || withoutTags.matches("^\\s*$")) {
            return false;
        }
        
        // 检查是否只包含参数占位符
        String withoutParams = withoutTags.replaceAll("#\\{?\\w+\\}?", "").replaceAll("#\\w+#", "").trim();
        if (withoutParams.isEmpty() || withoutParams.matches("^[\\s,=]*$")) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 预处理SQL以解决JSQLParser解析问题
     */
    private String preprocessSqlForParser(String sql) {
        if (sql == null) {
            return "";
        }
        
        String processed = sql;
        
        // 处理 'where 1=1' 语法，JSQLParser可能无法正确解析
        // 将 'where 1=1' 替换为 'where 1 = 1'
        processed = processed.replaceAll("(?i)\\bwhere\\s+1=1\\b", "where 1 = 1");
        
        // 处理 'and 1=1' 语法
        processed = processed.replaceAll("(?i)\\band\\s+1=1\\b", "and 1 = 1");
        
        // 处理 'or 1=1' 语法
        processed = processed.replaceAll("(?i)\\bor\\s+1=1\\b", "or 1 = 1");
        
        // 处理Oracle特有的DUAL表语法
        processed = processed.replaceAll("(?i)\\bfrom\\s+dual\\b", "from dual");
        
        // 处理Oracle的ROWNUM
        processed = processed.replaceAll("(?i)\\brownum\\s*<=?\\s*\\d+", "rownum <= 1000");
        
        // 处理可能的语法问题：连续的逗号
        processed = processed.replaceAll(",\\s*,+", ",");
        
        // 处理可能的语法问题：SET后面直接跟逗号
        processed = processed.replaceAll("(?i)\\bset\\s*,", "set ");
        
        // 处理WHERE后面直接跟AND的问题
        processed = processed.replaceAll("(?i)\\bwhere\\s+and\\b", "where 1=1 and");
        
        // 处理WHERE后面直接跟OR的问题
        processed = processed.replaceAll("(?i)\\bwhere\\s+or\\b", "where 1=1 or");
        
        // 处理多余的AND/OR操作符
        processed = processed.replaceAll("(?i)\\band\\s+and\\b", "and");
        processed = processed.replaceAll("(?i)\\bor\\s+or\\b", "or");
        
        // 处理空括号
        processed = processed.replaceAll("\\(\\s*\\)", "");
        
        // 处理VALUES后面的空括号或不完整的VALUES语句
        processed = processed.replaceAll("(?i)\\bvalues\\s*\\(\\s*\\)", "values (null)");
        
        // 处理SET子句中的连续逗号
        processed = processed.replaceAll("(?i)\\bset\\s+,", "set ");
        
        // 处理空字符串赋值问题（如 losetime=''）
        processed = processed.replaceAll("=\\s*''", "= NULL");
        
        // 处理CDATA标签内的制表符和换行符
        processed = processed.replaceAll("\\t+", " ").replaceAll("\\r?\\n", " ");
        
        // 处理Oracle的不等于操作符
        processed = processed.replaceAll("!=", "<>");
        
        // 处理动态标签中的order by语句位置问题
        processed = processed.replaceAll("(?i)\\s+order\\s+by\\s+[^)]+\\s*\\)", ")");
        
        // 处理中文逗号
        processed = processed.replaceAll("，", ",");
        
        return processed;
    }

    @Override
    public String fixMybatisSqlToStandardSql(String sql, String elementType) {
        // 预处理SQL以解决JSQLParser解析问题
        sql = preprocessSqlForParser(sql);
        if (sql == null) {
            return "";
        }
        
        String fixed = sql;
        logger.debug("开始修复SQL - 类型: {}, 原始长度: {}", elementType, sql.length());
        
        // 0. 处理CDATA包裹的SQL内容
        fixed = fixed.trim();
        
        // 处理完整的CDATA标签
        if (fixed.startsWith("<![CDATA[") && fixed.endsWith("]]")) {
            fixed = fixed.substring(9, fixed.length() - 2).trim();
            logger.debug("移除完整CDATA包裹，处理后长度: {}", fixed.length());
        }
        // 处理不完整的CDATA开始标签
        else if (fixed.startsWith("<![CDATA[")) {
            fixed = fixed.substring(9).trim();
            logger.debug("移除不完整CDATA开始标签，处理后长度: {}", fixed.length());
        }
        // 处理不完整的CDATA结束标签
        else if (fixed.endsWith("]]")) {
            fixed = fixed.substring(0, fixed.length() - 2).trim();
            logger.debug("移除不完整CDATA结束标签，处理后长度: {}", fixed.length());
        }
        
        // 处理中间可能存在的CDATA标签残留
        fixed = fixed.replaceAll("<!\\[CDATA\\[", "").replaceAll("\\]\\]>", "").trim();
        logger.debug("清理CDATA标签残留后长度: {}", fixed.length());
        
        // 1. 预处理：解码XML实体
        fixed = decodeXmlEntities(fixed);
        
        // 2. 修复常见的转义问题
        fixed = fixEscapeIssues(fixed);
        
        // 3. 处理include标签（需要在处理动态标签之前）
        fixed = processIncludeTags(fixed);
        
        // 4. 智能处理MyBatis动态标签
        fixed = processMybatisDynamicTags(fixed, elementType);
        
        // 5. 修复缺少#号的参数占位符
        fixed = fixMissingHashInParameters(fixed);
        
        // 6. 多层清理确保彻底移除所有XML标签
        fixed = thoroughlyRemoveXmlTags(fixed);
        
        // 如果返回null，表示跳过此SQL的解析
        if (fixed == null) {
            return null;
        }
        
        // 7. 替换MyBatis参数为占位符
        fixed = fixed.replaceAll("#\\{[^}]+\\}", "''");
        fixed = fixed.replaceAll("\\$\\{[^}]+\\}", "'''");
        
        // 7. 清理注释和特殊字符
        fixed = fixed.replaceAll("/\\*.*?\\*/", " ");
        fixed = fixed.replaceAll("[;{}]", " ");
        
        // 8. 根据SQL类型进行特定修复
        fixed = fixByElementType(fixed, elementType);
        
        // 9. 修复WHERE子句中的AND问题
        fixed = fixWhereClauseAndIssue(fixed);
        
        // 10. 修复1=1条件的位置问题
        fixed = fix1EqualsTo1Position(fixed);
        
        // 11. 最终清理
        fixed = fixed.replaceAll("\\s+", " ").trim();
        
        if (logger.isTraceEnabled()) {
            logger.trace("SQL修复完成 - 原始长度: {}, 修复后长度: {}", sql.length(), fixed.length());
        }
        
        return fixed;
    }
    
    /**
     * 解码XML实体，将XML实体转换为对应的字符
     */
    private String decodeXmlEntities(String sql) {
        if (sql == null) {
            return "";
        }
        
        String decoded = sql;
        
        // 处理基本的XML实体
        decoded = decoded.replace("&lt;", "<");
        decoded = decoded.replace("&gt;", ">");
        decoded = decoded.replace("&amp;", "&");
        decoded = decoded.replace("&quot;", "\"");
        decoded = decoded.replace("&apos;", "'");
        
        // 处理数字字符引用（十进制）
        decoded = decoded.replaceAll("&#(\\d+);", "");
        
        // 处理十六进制字符引用
        decoded = decoded.replaceAll("&#x([0-9a-fA-F]+);", "");
        
        return decoded;
    }

    /**
     * 修复转义问题，特别是正则表达式中的转义字符
     */
    private String fixEscapeIssues(String sql) {
        if (sql == null) {
            return "";
        }
        
        String fixed = sql;
        
        // 特别处理从 XML 中解析出来的多层转义字符
        // 处理 \\\\d -> \\d -> \d -> [0-9] 的完整链条
        
        // 第一层：处理四层反斜杠 \\\\\\\\d
        fixed = fixed.replaceAll("'\\\\\\\\\\\\\\\\d'", "'[0-9]'");
        fixed = fixed.replaceAll("\"\\\\\\\\\\\\\\\\d\"", "\"[0-9]\"");
        
        // 第二层：处理三层反斜杠 \\\\\\d  
        fixed = fixed.replaceAll("'\\\\\\\\\\\\d'", "'[0-9]'");
        fixed = fixed.replaceAll("\"\\\\\\\\\\\\d\"", "\"[0-9]\"");
        
        // 第三层：处理双反斜杠 \\\\d
        fixed = fixed.replaceAll("'\\\\\\\\d'", "'[0-9]'");
        fixed = fixed.replaceAll("\"\\\\\\\\d\"", "\"[0-9]\"");
        
        // 第四层：处理单反斜杠 \\d
        fixed = fixed.replaceAll("'\\\\d'", "'[0-9]'");
        fixed = fixed.replaceAll("\"\\\\d\"", "\"[0-9]\"");
        
        // 处理其他正则字符类
        // \w -> [a-zA-Z0-9_]
        fixed = fixed.replaceAll("'\\\\\\\\\\\\\\\\w'", "'[a-zA-Z0-9_]'");
        fixed = fixed.replaceAll("'\\\\\\\\\\\\w'", "'[a-zA-Z0-9_]'");
        fixed = fixed.replaceAll("'\\\\\\\\w'", "'[a-zA-Z0-9_]'");
        fixed = fixed.replaceAll("'\\\\w'", "'[a-zA-Z0-9_]'");
        fixed = fixed.replaceAll("\"\\\\\\\\\\\\\\\\w\"", "\"[a-zA-Z0-9_]\"");
        fixed = fixed.replaceAll("\"\\\\\\\\\\\\w\"", "\"[a-zA-Z0-9_]\"");
        fixed = fixed.replaceAll("\"\\\\\\\\w\"", "\"[a-zA-Z0-9_]\"");
        fixed = fixed.replaceAll("\"\\\\w\"", "\"[a-zA-Z0-9_]\"");
        
        // \s -> [ \t\n\r]
        fixed = fixed.replaceAll("'\\\\\\\\\\\\\\\\s'", "'[ \\t\\n\\r]'");
        fixed = fixed.replaceAll("'\\\\\\\\\\\\s'", "'[ \\t\\n\\r]'");
        fixed = fixed.replaceAll("'\\\\\\\\s'", "'[ \\t\\n\\r]'");
        fixed = fixed.replaceAll("'\\\\s'", "'[ \\t\\n\\r]'");
        fixed = fixed.replaceAll("\"\\\\\\\\\\\\\\\\s\"", "\"[ \\t\\n\\r]\"");
        fixed = fixed.replaceAll("\"\\\\\\\\\\\\s\"", "\"[ \\t\\n\\r]\"");
        fixed = fixed.replaceAll("\"\\\\\\\\s\"", "\"[ \\t\\n\\r]\"");
        fixed = fixed.replaceAll("\"\\\\s\"", "\"[ \\t\\n\\r]\"");
        
        // 处理其他转义字符
        // \n
        fixed = fixed.replaceAll("'\\\\\\\\\\\\\\\\n'", "'\\n'");
        fixed = fixed.replaceAll("'\\\\\\\\\\\\n'", "'\\n'");
        fixed = fixed.replaceAll("'\\\\\\\\n'", "'\\n'");
        fixed = fixed.replaceAll("'\\\\n'", "'\\n'");
        
        // \t
        fixed = fixed.replaceAll("'\\\\\\\\\\\\\\\\t'", "'\\t'");
        fixed = fixed.replaceAll("'\\\\\\\\\\\\t'", "'\\t'");
        fixed = fixed.replaceAll("'\\\\\\\\t'", "'\\t'");
        fixed = fixed.replaceAll("'\\\\t'", "'\\t'");
        
        // 清理任何残留的多余反斜杠
        fixed = fixed.replaceAll("\\\\\\\\\\\\\\\\", "\\\\");
        fixed = fixed.replaceAll("\\\\\\\\\\\\", "\\\\");
        fixed = fixed.replaceAll("\\\\\\\\", "\\\\");
        
        return fixed;
    }
    
    /**
     * 彻底移除XML标签的多层清理方法
     */
    private String thoroughlyRemoveXmlTags(String sql) {
        if (sql == null) {
            return "";
        }
        
        String processed = sql;
        System.out.println("thoroughlyRemoveXmlTags - 输入: " + processed);
        
        // 预处理：先处理CDATA包裹的内容，提取其中的SQL
        processed = processed.trim();
        
        // 处理完整的CDATA标签
        if (processed.startsWith("<![CDATA[") && processed.endsWith("]]")) {
            processed = processed.substring(9, processed.length() - 2).trim();
            System.out.println("thoroughlyRemoveXmlTags - CDATA处理后: " + processed);
        }
        // 处理不完整的CDATA开始标签
        else if (processed.startsWith("<![CDATA[")) {
            processed = processed.substring(9).trim();
            System.out.println("thoroughlyRemoveXmlTags - 不完整CDATA开始处理后: " + processed);
        }
        // 处理不完整的CDATA结束标签
        else if (processed.endsWith("]]")) {
            processed = processed.substring(0, processed.length() - 2).trim();
            System.out.println("thoroughlyRemoveXmlTags - 不完整CDATA结束处理后: " + processed);
        }
        
        // 处理中间可能存在的CDATA标签残留
        processed = processed.replaceAll("<!\\[CDATA\\[", "").replaceAll("\\]\\]>", "").trim();
        
        // 修复缺少#号的MyBatis参数占位符
        processed = fixMissingHashInParameters(processed);
        
        // 处理复杂嵌套标签
        processed = processComplexNestedTags(processed);
        if (processed == null) {
            // 如果返回null，表示跳过此SQL的解析
            return null;
        }
        
        // 第一轮：智能移除XML标签，保留SQL比较操作符
        processed = smartRemoveXmlTags(processed);
        
        // 跳过第二轮处理，因为它会误删除SQL比较操作符
        
        // 第三轮：最后的清理，使用智能方法
        processed = cleanRemainingXmlWhilePreservingSqlOperators(processed);
        
        // 清理多余的逗号（特别是select语句中的情况）
        processed = cleanExtraCommas(processed);
        
        // 清理多余的空白
        processed = processed.replaceAll("\\s+", " ").trim();
        
        return processed;
    }
    
    /**
     * 修复缺少#号的MyBatis参数占位符
     * 将 {paramName,jdbcType=XXX} 修复为 #{paramName,jdbcType=XXX}
     */
    private String fixMissingHashInParameters(String sql) {
        if (sql == null) {
            return "";
        }
        
        // 匹配缺少#号的参数占位符模式：{paramName,jdbcType=XXX}
        // 但要避免匹配已经正确的 #{...} 和 ${...} 格式
        Pattern missingHashPattern = Pattern.compile("(?<!#)(?<!\\$)\\{([^}]+,jdbcType=[^}]+)\\}");
        Matcher matcher = missingHashPattern.matcher(sql);
        
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            String paramContent = matcher.group(1);
            // 替换为正确的 #{...} 格式
            matcher.appendReplacement(result, "#{" + paramContent + "}");
            System.out.println("修复参数占位符: {" + paramContent + "} -> #{" + paramContent + "}");
        }
        matcher.appendTail(result);
        
        // 修复CALLABLE语句中的mode参数
        result = new StringBuffer(fixCallableStatementParameters(result.toString()));
        
        // 修复foreach标签在values中的问题
        result = new StringBuffer(fixForeachInValues(result.toString()));
        
        return result.toString();
    }
    
    /**
     * 修复CALLABLE语句中的mode参数
     * 将 #{param,mode=IN} 修复为 #{param}
     */
    private String fixCallableStatementParameters(String sql) {
        if (sql == null || !sql.contains("call")) {
            return sql;
        }
        
        // 匹配包含mode属性的参数：#{param,mode=IN/OUT,jdbcType=XXX}
        Pattern callableParamPattern = Pattern.compile("#\\{([^,}]+),mode=[^,}]+([^}]*)\\}");
        Matcher matcher = callableParamPattern.matcher(sql);
        
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            String paramName = matcher.group(1);
            String remainingAttrs = matcher.group(2);
            
            // 保留jdbcType等其他属性，移除mode属性
            String replacement;
            if (remainingAttrs != null && !remainingAttrs.trim().isEmpty()) {
                replacement = "#{" + paramName + remainingAttrs + "}";
            } else {
                replacement = "#{" + paramName + "}";
            }
            
            matcher.appendReplacement(result, replacement);
            System.out.println("修复CALLABLE参数: " + matcher.group(0) + " -> " + replacement);
        }
        matcher.appendTail(result);
        
        return result.toString();
    }
    
    /**
     * 处理foreach标签
     */
    private String processForeachTags(String sql) {
        if (sql == null) {
            return sql;
        }
        
        // 处理foreach标签，将其替换为占位符
        // 更灵活的正则表达式，支持不同的属性顺序和嵌套内容
        String foreachPattern = "<foreach[^>]*?>(.*?)</foreach>";
        String processed = sql.replaceAll("(?s)" + foreachPattern, "''");
        
        return processed;
    }
    
    /**
     * 处理复杂嵌套标签
     */
    private String processComplexNestedTags(String sql) {
        if (sql == null) {
            return sql;
        }
        
        String processed = sql;
        
        // 检测并跳过极其复杂的嵌套结构（如MyBatis Generator生成的动态查询）
        if (processed.contains("<where>") && processed.contains("<trim") && 
            processed.contains("<foreach") && processed.contains("<choose") &&
            processed.contains("criterion")) {
            // 这类复杂结构通常是MyBatis Generator生成的，直接跳过不解析
            return null; // 返回null表示跳过此SQL的解析
        }
        
        // 特殊处理where条件中的复杂嵌套结构
        if (processed.contains("<where>")) {
            // 检查是否包含复杂的嵌套结构
            if (processed.contains("<trim") && processed.contains("<foreach") && processed.contains("<choose")) {
                // 对于极其复杂的嵌套，直接简化为基本WHERE条件
                processed = processed.replaceAll("(?s)<where[^>]*?>(.*?)</where>", "WHERE 1=1");
                return processed;
            } else {
                // 对于简单的where标签，保留内容但移除标签
                processed = processed.replaceAll("(?s)<where[^>]*?>(.*?)</where>", "WHERE $1");
            }
        }
        
        // 处理复杂的criterion动态条件结构
        if (processed.contains("criterion")) {
            // 简化criterion相关的复杂条件
            processed = processed.replaceAll("(?s)\\$\\{criterion\\.condition\\}[^<]*?<foreach[^>]*?>[^<]*?</foreach>", "column_name IN ('value1', 'value2')");
            processed = processed.replaceAll("(?s)and \\$\\{criterion\\.condition\\}[^<]*", "AND column_name = 'value'");
        }
        
        String previous;
        int maxIterations = 10; // 防止无限循环
        int iteration = 0;
        
        // 迭代处理，直到没有更多标签可以处理
        do {
            previous = processed;
            iteration++;
            
            // 先处理foreach标签，特别是IN语句中的foreach
            if (processed.contains("<foreach")) {
                // 特殊处理IN语句中的foreach
                processed = processed.replaceAll("(?s)\\s+in\\s*<foreach[^>]*?>.*?</foreach>", " IN ('1')");
                processed = processed.replaceAll("(?s)\\s+IN\\s*<foreach[^>]*?>.*?</foreach>", " IN ('1')");
                // 处理换行的情况
                processed = processed.replaceAll("(?s)in\\s*\\r?\\n\\s*<foreach[^>]*?>.*?</foreach>", "IN ('1')");
                processed = processed.replaceAll("(?s)IN\\s*\\r?\\n\\s*<foreach[^>]*?>.*?</foreach>", "IN ('1')");
                
                // 处理其他foreach情况
                if (processed.contains("values") || processed.contains("VALUES")) {
                    processed = processed.replaceAll("(?s)<foreach[^>]*?>(.*?)</foreach>", "(1)");
                } else {
                    processed = processed.replaceAll("(?s)<foreach[^>]*?>(.*?)</foreach>", "1=1");
                }
            }
            
            // 处理if标签
            processed = processed.replaceAll("(?s)<if[^>]*?>(.*?)</if>", "$1");
            
            // 处理choose/when/otherwise标签
            processed = processed.replaceAll("(?s)<choose[^>]*?>(.*?)</choose>", "$1");
            processed = processed.replaceAll("(?s)<when[^>]*?>(.*?)</when>", "$1");
            processed = processed.replaceAll("(?s)<otherwise[^>]*?>(.*?)</otherwise>", "$1");
            
            // 处理trim标签
            processed = processed.replaceAll("(?s)<trim[^>]*?>(.*?)</trim>", "$1");
            
            // 处理set标签
            processed = processed.replaceAll("(?s)<set[^>]*?>(.*?)</set>", "SET $1");
            
            // 清理多余的空白和逻辑操作符
            processed = processed.replaceAll("\\s+", " ");
            processed = processed.replaceAll("\\s*and\\s+and\\s*", " and ");
            processed = processed.replaceAll("\\s*or\\s+or\\s*", " or ");
            processed = processed.replaceAll(",\\s*,", ",");
            processed = processed.replaceAll("^\\s*,|,\\s*$", "");
            processed = processed.replaceAll("\\(\\s*\\)", "(1)");
            
        } while (!processed.equals(previous) && 
                 (processed.contains("<foreach") || processed.contains("<choose") || 
                  processed.contains("<when") || processed.contains("<trim") || 
                  processed.contains("<if")) && 
                 iteration < maxIterations);
        
        // 修复常见的SQL语法错误
        // 1. 修复SELECT拼写错误
        processed = processed.replaceAll("\\bsele\\b", "SELECT");
        
        // 2. 修复AND ROWNUM位置错误 - 需要添加WHERE子句
        if (processed.contains("AND ROWNUM")) {
            // 如果没有WHERE子句，在AND ROWNUM前添加WHERE
            processed = processed.replaceAll("FROM\\s+([^\\s]+)\\s+([^\\s]+)\\s+AND\\s+ROWNUM", "FROM $1 $2 WHERE ROWNUM");
            // 如果已有WHERE子句，将AND ROWNUM改为AND ROWNUM
            processed = processed.replaceAll("WHERE\\s+AND\\s+ROWNUM", "WHERE ROWNUM");
        }
        
        // 3. 修复未闭合的注释问题
        if (processed.contains("<!--") && !processed.contains("-->")) {
            // 如果有开始注释但没有结束注释，添加结束注释
            processed = processed + " -->";
        }
        
        // 4. 处理复杂的动态SQL标签，进一步简化
        if (processed.contains("<foreach")) {
            // 处理IN语句中的foreach - 更精确的匹配
            processed = processed.replaceAll("(?s)\\bin\\s*<foreach[^>]*>.*?</foreach>", " IN ('1')");
            processed = processed.replaceAll("(?s)\\bIN\\s*<foreach[^>]*>.*?</foreach>", " IN ('1')");
            // 处理换行的情况
            processed = processed.replaceAll("(?s)\\bin\\s*\\r?\\n\\s*<foreach[^>]*>.*?</foreach>", " IN ('1')");
            processed = processed.replaceAll("(?s)\\bIN\\s*\\r?\\n\\s*<foreach[^>]*>.*?</foreach>", " IN ('1')");
            // 处理其他foreach情况
            processed = processed.replaceAll("(?s)<foreach[^>]*>(.*?)</foreach>", "$1");
        }
        
        // 5. 处理choose/when/otherwise标签的残留
        if (processed.contains("<choose>")) {
            // 简化choose标签，只保留第一个when条件的内容
            processed = processed.replaceAll("(?s)<choose>.*?<when[^>]*>(.*?)</when>.*?</choose>", "$1");
        }
        
        // 8. 处理复杂的where条件嵌套
        if (processed.contains("<where>") && processed.contains("<trim")) {
            // 对于复杂的where+trim+foreach组合，简化为基本WHERE条件
            processed = processed.replaceAll("(?s)<where>.*?</where>", "WHERE 1=1");
        }
        
        // 9. 处理criterion动态条件
        if (processed.contains("criterion")) {
            // 移除所有criterion相关的动态条件，替换为简单条件
            processed = processed.replaceAll("\\$\\{criterion\\.[^}]*\\}", "column");
            processed = processed.replaceAll("#\\{criterion\\.[^}]*\\}", "'value'");
        }
        
        // 6. 处理注释内容导致的解析错误
        if (processed.contains("<!--")) {
            // 移除所有注释内容
            processed = processed.replaceAll("(?s)<!--.*?-->", "");
        }
        
        // 7. 清理可能导致解析错误的特殊字符和格式
        processed = processed.replaceAll("\\r\\n", " ");
        processed = processed.replaceAll("\\n", " ");
        processed = processed.replaceAll("\\r", " ");
        processed = processed.replaceAll("\\s+", " ");
        processed = processed.trim();
        
        return processed;
    }
    
    /**
     * 修复foreach标签在values中的问题
     * 确保foreach生成的values结构完整
     */
    private String fixForeachInValues(String sql) {
        if (sql == null || !sql.toLowerCase().contains("values")) {
            return sql;
        }
        
        // 检查是否是不完整的values结构（只有一个foreach参数）
        Pattern incompleteValuesPattern = Pattern.compile("values\\s*\\(\\s*''\\s*\\)");
        if (incompleteValuesPattern.matcher(sql).find()) {
            // 如果发现不完整的values结构，尝试修复
            String fixed = sql.replaceAll("values\\s*\\(\\s*''\\s*\\)", "values ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')");
            System.out.println("修复不完整的values结构");
            return fixed;
        }
        
        return sql;
    }
    
    /**
     * 清理多余的逗号，特别是处理条件标签移除后留下的逗号
     */
    private String cleanExtraCommas(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return sql;
        }
        
        String processed = sql;
        
        // 处理 select 语句中的多余逗号
        // 匹配模式：select 后面直接跟逗号的情况
        processed = processed.replaceAll("(?i)\\bselect\\s*,\\s*", "select ");
        
        // 处理连续的逗号
        processed = processed.replaceAll(",\\s*,+", ",");
        
        // 处理逗号后直接跟 from 的情况
        processed = processed.replaceAll(",\\s+(?i)from\\b", " from");
        
        // 处理其他可能的多余逗号情况
        processed = processed.replaceAll("\\s*,\\s*(?i)(where|group|order|having|limit)\\b", " $1");
        
        return processed;
    }
    
    /**
     * 智能清理残留的XML标签，同时保留SQL比较操作符
     */
    private String cleanRemainingXmlWhilePreservingSqlOperators(String sql) {
        if (sql == null) {
            return "";
        }
        
        String processed = sql;
        
        // 移除明显的XML标签模式（包含字母的尖括号内容）
        // 例如: <if>, <when>, <choose>, <trim> 等
        processed = processed.replaceAll("<\\s*/?\\s*[a-zA-Z][^>]*>", " ");
        
        // 移除单独的 < 或 > 如果它们看起来是XML标签残留
        // 但要保留明显的SQL比较操作符模式
        
        // 保护SQL比较操作符的模式：
        // COLUMN_NAME < value, COLUMN_NAME > value, COLUMN_NAME <= value, COLUMN_NAME >= value
        // 临时替换SQL比较操作符为占位符，避免被误删
        Map<String, String> operators = new HashMap<>();
        operators.put("TEMP_LT_OP", " < ");
        operators.put("TEMP_GT_OP", " > ");
        operators.put("TEMP_LE_OP", " <= ");
        operators.put("TEMP_GE_OP", " >= ");
        
        // 替换为临时占位符 - 支持多种格式：空格、引号、变量等
        processed = processed.replaceAll("\\s+<=\\s*", " TEMP_LE_OP ");
        processed = processed.replaceAll("\\s+>=\\s*", " TEMP_GE_OP ");
        processed = processed.replaceAll("\\s+<\\s*", " TEMP_LT_OP ");
        processed = processed.replaceAll("\\s+>\\s*", " TEMP_GT_OP ");
        
        // 现在可以安全地移除剩余的 < 和 > （这些应该是XML标签残留）
        processed = processed.replaceAll("[<>]", " ");
        
        // 恢复SQL比较操作符
        for (Map.Entry<String, String> entry : operators.entrySet()) {
            processed = processed.replace(entry.getKey(), entry.getValue());
        }
        
        return processed;
    }
    
    /**
     * 根据SQL元素类型进行特定修复
     */
    private String fixByElementType(String sql, String elementType) {
        if (sql == null) {
            return "";
        }
        
        String fixed = sql;
        String lower = fixed.trim().toLowerCase();
        
        switch (elementType.toLowerCase()) {
            case "select":
                fixed = fixSelectStatement(fixed, lower);
                break;
            case "update":
                fixed = fixUpdateStatement(fixed, lower);
                break;
            case "insert":
                fixed = fixInsertStatement(fixed, lower);
                break;
            case "delete":
                fixed = fixDeleteStatement(fixed, lower);
                break;
        }
        
        return fixed;
    }
    
    /**
     * 修复SELECT语句的特定问题
     */
    private String fixSelectStatement(String sql, String lowerSql) {
        String fixed = sql;
        
        // 处理 select 'literal' as alias, from table 的情况（去掉多余的逗号）
        if (lowerSql.matches("select\\s+['\"]?[^'\"]*['\"]?\\s+as\\s+\\w+,?\\s*from.*")) {
            fixed = fixed.replaceFirst(",\\s*from", " from");
        }
        
        // 处理 select from table 的情况（缺少字段）
        if (lowerSql.matches("select\\s+from.*")) {
            fixed = fixed.replaceFirst("select\\s+from", "select 1 as PLACEHOLDER from");
        }
        
        // 处理 select FUNCTION(...) from table 的情况
        if (lowerSql.matches("select\\s+\\w+\\s*\\([^)]*\\)\\s*from.*")) {
            // 保持函数调用，这很重要用于兼容性检测
        }
        
        return fixed;
    }
    
    /**
     * 修复UPDATE语句的特定问题
     */
    private String fixUpdateStatement(String sql, String lowerSql) {
        String fixed = sql;
        
        // update ... where ... 缺set
        if (lowerSql.matches("update\\s+\\w+\\s+where.*")) {
            String tableName = getTableNameFromUpdate(fixed);
            String setClause = tableName + "_field = 'value'";
            fixed = fixed.replaceFirst("update(\\s+\\w+)\\s+where", "update$1 set " + setClause + " where");
        }
        
        // update ... set ... 缺where
        if (lowerSql.matches("update\\s+\\w+\\s+set[\\s\\S]*[^w]$")) {
            if (!lowerSql.contains("where")) {
                fixed = fixed + " where 1=1";
            }
        }
        
        // update TABLE 只有表名，自动补全set和where
        if (lowerSql.matches("update\\s+\\w+\\s*$")) {
            String table = getTableNameFromUpdate(fixed);
            fixed = "update " + table + " set " + table + "_field = 'value' where 1=1";
        }
        
        return fixed;
    }
    
    /**
     * 修复INSERT语句的特定问题
     */
    private String fixInsertStatement(String sql, String lowerSql) {
        String fixed = sql;
        
        if (lowerSql.matches("insert\\s+into\\s+\\w+\\s*$")) {
            String table = getTableNameFromInsert(fixed);
            fixed = "insert into " + table + " (ID) values (1)";
        }
        
        return fixed;
    }
    
    /**
     * 修复DELETE语句的特定问题
     */
    private String fixDeleteStatement(String sql, String lowerSql) {
        String fixed = sql;
        
        // 确保DELETE语句有基本的WHERE条件（如果没有的话）
        if (lowerSql.matches("delete\\s+from\\s+\\w+\\s*$")) {
            fixed = fixed + " where 1=1";
        }
        
        return fixed;
    }

    /**
     * 提取update语句表名
     */
    private String getTableNameFromUpdate(String sql) {
        try {
            String[] parts = sql.trim().split("\\s+");
            if (parts.length >= 2) {
                return parts[1];
            }
        } catch (Exception e) {}
        return "TABLE_PLACEHOLDER";
    }

    /**
     * 从插入语句中获取表名
     */
    private String getTableNameFromInsert(String sql) {
        try {
            String[] parts = sql.trim().split("\\s+");
            if (parts.length >= 3) {
                return parts[2];
            }
        } catch (Exception e) {}
        return "TABLE_PLACEHOLDER";
    }
    
    /**
     * 清理动态内容中的条件标签
     */
    private String cleanDynamicContent(String content) {
        if (content == null) {
            return "";
        }
        
        String cleaned = content;
        
        // 检查是否是UPDATE语句的SET子句
        boolean isUpdateSetClause = cleaned.toLowerCase().contains("set ") || 
                                   cleaned.matches("(?s).*\\w+\\s*=\\s*#\\{?\\w+\\}?.*");
        
        if (isUpdateSetClause) {
            // 对于UPDATE语句，处理SET子句中的条件标签
            // 特别处理prepend=","的情况，将其转换为逗号分隔的赋值语句
            Pattern isNotEmptyPattern = Pattern.compile("<isNotEmpty[^>]*prepend=\"[^\"]*\"[^>]*>(.*?)</isNotEmpty>", Pattern.DOTALL);
            Matcher matcher = isNotEmptyPattern.matcher(cleaned);
            StringBuilder result = new StringBuilder();
            
            while (matcher.find()) {
                 String matchedContent = matcher.group(1).trim();
                 if (result.length() > 0) {
                     result.append(", ");
                 }
                 result.append(matchedContent);
             }
            
            if (result.length() > 0) {
                cleaned = result.toString();
            } else {
                // 如果没有匹配到prepend模式，使用原有逻辑
                cleaned = cleaned.replaceAll("<isNotEmpty[^>]*>(.*?)</isNotEmpty>", "$1");
                cleaned = cleaned.replaceAll("<isEmpty[^>]*>(.*?)</isEmpty>", "");
                cleaned = cleaned.replaceAll("<isNotNull[^>]*>(.*?)</isNotNull>", "$1");
                cleaned = cleaned.replaceAll("<isNull[^>]*>(.*?)</isNull>", "");
                cleaned = cleaned.replaceAll("<isEqual[^>]*>(.*?)</isEqual>", "$1");
                cleaned = cleaned.replaceAll("<isNotEqual[^>]*>(.*?)</isNotEqual>", "");
            }
            
            // 确保SET关键字存在
            if (!cleaned.toLowerCase().trim().startsWith("set")) {
                cleaned = "SET " + cleaned;
            }
            
            // 清理多余的逗号和连接符
            cleaned = cleaned.replaceAll("\\s*,\\s*,\\s*", ", ");
            cleaned = cleaned.replaceAll("\\s+and\\s+", ", ");
            cleaned = cleaned.replaceAll("SET\\s+,", "SET ");
            cleaned = cleaned.replaceAll(",\\s*$", "");
        } else {
            // 对于其他情况，处理各种动态标签
            cleaned = cleaned.replaceAll("<isNotEmpty[^>]*>(.*?)</isNotEmpty>", "$1");
            cleaned = cleaned.replaceAll("<isEmpty[^>]*>(.*?)</isEmpty>", "");
            cleaned = cleaned.replaceAll("<isNotNull[^>]*>(.*?)</isNotNull>", "$1");
            cleaned = cleaned.replaceAll("<isNull[^>]*>(.*?)</isNull>", "");
            cleaned = cleaned.replaceAll("<isEqual[^>]*>(.*?)</isEqual>", "$1");
            cleaned = cleaned.replaceAll("<isNotEqual[^>]*>(.*?)</isNotEqual>", "");
            cleaned = cleaned.replaceAll("<isGreaterThan[^>]*>(.*?)</isGreaterThan>", "$1");
            cleaned = cleaned.replaceAll("<isLessThan[^>]*>(.*?)</isLessThan>", "$1");
        }
        
        // 处理动态标签的prepend属性导致的重复关键字
        cleaned = cleaned.replaceAll("(?i)\\bAND\\s+AND\\b", "AND");
        cleaned = cleaned.replaceAll("(?i)\\bOR\\s+OR\\b", "OR");
        cleaned = cleaned.replaceAll("(?i)\\bWHERE\\s+AND\\b", "WHERE");
        cleaned = cleaned.replaceAll("(?i)\\bWHERE\\s+OR\\b", "WHERE");
        
        // 清理多余的空格和换行
        cleaned = cleaned.replaceAll("\\s+", " ").trim();
        
        return cleaned;
    }
    
    /**
     * 智能处理MyBatis动态标签，转换为标准SQL
     */
    private String processMybatisDynamicTags(String sql, String elementType) {
        if (sql == null || sql.trim().isEmpty()) {
            return sql;
        }
        
        String processed = sql;
        logger.debug("动态标签处理开始 - 元素类型: {}, 原始SQL长度: {}", elementType, sql.length());
        
        try {
            // 处理INSERT语句的动态标签
            if ("insert".equalsIgnoreCase(elementType)) {
                processed = processInsertDynamicTags(processed);
            }
            // 处理UPDATE语句的动态标签
            else if ("update".equalsIgnoreCase(elementType)) {
                processed = processUpdateDynamicTags(processed);
            }
            // 处理SELECT语句的动态标签
            else if ("select".equalsIgnoreCase(elementType)) {
                processed = processSelectDynamicTags(processed);
            }
            
            // 通用动态标签处理
            processed = processCommonDynamicTags(processed);
            
            // 最后确保彻底清除所有残留标签
            processed = removeAllRemainingTags(processed);
            
        } catch (Exception e) {
            logger.warn("处理MyBatis动态标签失败: {}, 使用原始SQL", e.getMessage());
            return sql;
        }
        
        return processed;
    }

    /**
     * 处理INSERT语句的动态标签
     */
    private String processInsertDynamicTags(String sql) {
        String processed = sql;
        
        // 特殊处理Oracle INSERT ALL语法
        processed = processInsertAllStatement(processed);
        
        // 先处理foreach标签
        processed = processForeachTags(processed);
        
        // 先处理内部的if标签，提取列名和值
        // 处理 <if test="..."> COLUMN_NAME, </if> 模式 - 提取列名
        String ifColumnPattern = "<if\\s+test=\"[^\"]*\"[^>]*?>\\s*([A-Za-z_][A-Za-z0-9_]*),?\\s*</if>";
        processed = processed.replaceAll("(?s)" + ifColumnPattern, "$1,");
        
        // 处理 <if test="..."> #{...}, </if> 模式 - 替换为空字符串值
        String ifValuePattern = "<if\\s+test=\"[^\"]*\"[^>]*?>\\s*#\\{[^}]+\\},?\\s*</if>";
        processed = processed.replaceAll("(?s)" + ifValuePattern, "'',");
        
        // 处理 <trim prefix="(" suffix=")" suffixOverrides=","> ... </trim>
        // 匹配列名部分的trim标签
        String columnTrimPattern = "<trim\\s+prefix=\"\\(\"\\s+suffix=\"\\)\"\\s+suffixOverrides=\",\"[^>]*?>(.*?)</trim>";
        processed = processed.replaceAll("(?s)" + columnTrimPattern, "($1)");
        
        // 处理 <trim prefix="values (" suffix=")" suffixOverrides=","> ... </trim>
        // 匹配值部分的trim标签
        String valuesTrimPattern = "<trim\\s+prefix=\"values\\s*\\(\"\\s+suffix=\"\\)\"\\s+suffixOverrides=\",\"[^>]*?>(.*?)</trim>";
        processed = processed.replaceAll("(?s)" + valuesTrimPattern, "values ($1)");
        
        // 清理多余的逗号和空白
        processed = processed.replaceAll(",\\s*\\)", ")");
        processed = processed.replaceAll(",\\s*,", ",");
        processed = processed.replaceAll("\\s+", " ");
        
        return processed;
    }

    /**
     * 处理Oracle INSERT ALL语法，将其转换为标准INSERT语句
     */
    private String processInsertAllStatement(String sql) {
        if (sql == null || !sql.toUpperCase().contains("INSERT ALL")) {
            return sql;
        }
        
        String processed = sql;
        
        // 检测INSERT ALL模式
        if (processed.toUpperCase().trim().startsWith("INSERT ALL")) {
            // 提取表名 - 查找INTO子句中的表名
            String tableNamePattern = "INTO\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*\\(";
            java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(tableNamePattern, java.util.regex.Pattern.CASE_INSENSITIVE);
            java.util.regex.Matcher matcher = pattern.matcher(processed);
            
            String tableName = "UNKNOWN_TABLE";
            if (matcher.find()) {
                tableName = matcher.group(1);
            }
            
            // 提取列名 - 查找INTO子句中的列定义
            String columnPattern = "INTO\\s+[A-Za-z_][A-Za-z0-9_]*\\s*\\(([^)]+)\\)";
            pattern = java.util.regex.Pattern.compile(columnPattern, java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.DOTALL);
            matcher = pattern.matcher(processed);
            
            String columns = "ID";
            if (matcher.find()) {
                columns = matcher.group(1).trim();
                // 清理列名中的换行符和多余空格
                columns = columns.replaceAll("\\s+", " ").trim();
            }
            
            // 将INSERT ALL转换为标准INSERT语句
            processed = "INSERT INTO " + tableName + " (" + columns + ") VALUES ('', '', '', '', '', '', '', '', '', '', '', '', '')";
            
            logger.debug("转换INSERT ALL语句: {} -> {}", sql.substring(0, Math.min(100, sql.length())), processed);
        }
        
        return processed;
    }

    /**
     * 处理UPDATE语句的动态标签
     */
    private String processUpdateDynamicTags(String sql) {
        String processed = sql;
        
        // 先处理内部的if标签，转换为标准赋值
        // 处理 <if test="..."> COLUMN = #{...}, </if> 模式
        String ifSetPattern = "<if\\s+test=\"[^\"]*\"[^>]*?>\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*#\\{[^}]+\\},?\\s*</if>";
        processed = processed.replaceAll("(?s)" + ifSetPattern, "$1 = '',");
        
        // 处理 <set> ... </set>
        processed = processed.replaceAll("(?s)<set[^>]*?>(.*?)</set>", "set $1");
        
        // 清理set子句中多余的逗号
        processed = processed.replaceAll("set\\s+(.*?),\\s*where", "set $1 where");
        processed = processed.replaceAll("set\\s+(.*?),\\s*$", "set $1");
        processed = processed.replaceAll("\\s+", " ");
        
        return processed;
    }

    /**
     * 处理SELECT语句的动态标签
     */
    private String processSelectDynamicTags(String sql) {
        String processed = sql;
        
        // 处理 <if test="distinct"> distinct </if>
        processed = processed.replaceAll("(?s)<if\\s+test=\"distinct\"[^>]*?>\\s*distinct\\s*</if>", "");
        
        return processed;
    }

    /**
     * 处理通用动态标签
     */
    private String processCommonDynamicTags(String sql) {
        String processed = sql;
        
        // 1. 处理 <if test="distinct"> distinct </if> - 保留distinct
        processed = processed.replaceAll("(?s)<if\\s+test=\"distinct\"[^>]*?>\\s*distinct\\s*</if>", "distinct");
        
        // 2. 处理其他所有的 <if test="..."> ... </if> - 提取内容但去掉if标签
        processed = processed.replaceAll("(?s)<if\\s+test=\"[^\"]*\"[^>]*?>(.*?)</if>", "$1");
        
        // 3. 处理复杂嵌套标签
        processed = processComplexNestedTags(processed);
        
        // 4. 处理 <where> ... </where> - 智能处理where条件
        if (processed.contains("<where>")) {
            // 如果SQL中已有where关键字，将<where>标签替换为AND
            if (processed.toLowerCase().contains(" where ")) {
                processed = processed.replaceAll("(?s)<where[^>]*?>(.*?)</where>", " AND ($1)");
            } else {
                processed = processed.replaceAll("(?s)<where[^>]*?>(.*?)</where>", " WHERE $1");
            }
            
            // 修复WHERE子句中开头的多余AND问题
            processed = fixWhereClauseAndIssue(processed);
        }
        
        // 5. 处理函数中的变量替换（to_char, DATE_FORMAT等）
        processed = replaceFunctionVariables(processed);
        
        // 6. 智能移除XML标签，保留SQL比较操作符
        processed = smartRemoveXmlTags(processed);
        
        // 7. 清理多余空格和换行
        processed = processed.replaceAll("\\s+", " ").trim();
        
        // 8. 修复1=1条件的位置问题
        processed = fix1EqualsTo1Position(processed);
        
        // 9. 修复order by的问题
        processed = processed.replaceAll("order by\\s*''", "");
        
        // 10. 统一替换所有#参数#为空字符串
        processed = replaceParametersWithEmptyString(processed);
        
        return processed;
    }
    
    /**
     * 智能移除XML标签，保留SQL比较操作符
     */
    private String smartRemoveXmlTags(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return sql;
        }
          
        String processed = sql;
        
        // 保护SQL比较操作符：临时替换为占位符
        Map<String, String> operators = new HashMap<>();
        operators.put("TEMP_LT_OP", " < ");
        operators.put("TEMP_GT_OP", " > ");
        operators.put("TEMP_LE_OP", " <= ");
        operators.put("TEMP_GE_OP", " >= ");
        
        // 替换SQL比较操作符为临时占位符
        processed = processed.replaceAll("\\s+<=\\s*", " TEMP_LE_OP ");
        processed = processed.replaceAll("\\s+>=\\s*", " TEMP_GE_OP ");
        processed = processed.replaceAll("\\s+<\\s*", " TEMP_LT_OP ");
        processed = processed.replaceAll("\\s+>\\s*", " TEMP_GT_OP ");
        
        // 现在可以安全地移除XML标签
        processed = processed.replaceAll("(?s)<[^>]+>", " ");
        
        // 恢复SQL比较操作符
        for (Map.Entry<String, String> entry : operators.entrySet()) {
            processed = processed.replace(entry.getKey(), entry.getValue());
        }
        
        return processed;
    }

    /**
     * 修复WHERE子句中开头的多余AND问题
     */
    private String fixWhereClauseAndIssue(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return sql;
        }
        
        String processed = sql;
        
        // 修复 "WHERE and ..." 的问题
        processed = processed.replaceAll("(?i)\\bWHERE\\s+and\\b", "WHERE");
        
        // 修复 "where and ..." 的问题  
        processed = processed.replaceAll("(?i)\\bwhere\\s+and\\b", "WHERE");
        
        // 修复AND子句中的多余and
        processed = processed.replaceAll("(?i)\\bAND\\s*\\(\\s*and\\b", "AND (");
        
        return processed;
    }

    /**
     * 修复1=1条件的位置问题
     */
    private String fix1EqualsTo1Position(String sql) {
        if (!sql.contains("1=1")) {
            return sql;
        }
        
        String processed = sql;
        
        // 情况1: "from TABLE 1=1" -> "from TABLE WHERE 1=1"
        processed = processed.replaceAll("(from\\s+\\w+)\\s+1=1", "$1 WHERE 1=1");
        
        // 情况2: UPDATE语句中的SET子句问题 - 更精确的处理
        if (processed.toLowerCase().contains("update") && processed.contains("set")) {
            // 处理 ", 1=1 where 1=1" 模式
            processed = processed.replaceAll("(?i),\\s*1=1\\s+where\\s+1=1", " WHERE 1=1");
            
            // 处理 " 1=1 where 1=1" 模式（没有前导逗号）
            processed = processed.replaceAll("(?i)\\s+1=1\\s+where\\s+1=1", " WHERE 1=1");
            
            // 处理包含"set"的复杂情况
            // 匹配 "set field = 'value', 1=1 where 1=1" 
            processed = processed.replaceAll("(?i)(set\\s+[^=]+=[^,]+(?:,\\s*[^=]+=[^,]+)*),\\s*1=1\\s+where\\s+1=1", "$1 WHERE 1=1");
            
            // 匹配 "set field = 'value' 1=1 where 1=1" 
            processed = processed.replaceAll("(?i)(set\\s+[^=]+=[^,]+(?:,\\s*[^=]+=[^,]+)*)\\s+1=1\\s+where\\s+1=1", "$1 WHERE 1=1");
        }
        
        // 情况3: 清理多余的1=1
        processed = processed.replaceAll("\\s+1=1\\s+where\\s+1=1", " WHERE 1=1");
        
        // 情况4: 清理末尾的逗号问题
        processed = processed.replaceAll(",\\s*WHERE\\s+1=1", " WHERE 1=1");
        
        // 情况5: "where 1=1 order by" 清理order by问题
        processed = processed.replaceAll("WHERE\\s+1=1\\s+order\\s+by\\s*''", "WHERE 1=1");
        
        return processed;
    }
    
    /**
     * 彻底移除所有剩余的XML标签
     */
    private String removeAllRemainingTags(String sql) {
        if (sql == null) {
            return "";
        }
        
        String processed = sql;

        // 智能移除XML标签，保留SQL比较操作符
        processed = smartRemoveXmlTags(processed);
        
        // 清理多余的空白
        processed = processed.replaceAll("\\s+", " ").trim();
        
        // 清理可能的语法问题
        processed = processed.replaceAll("\\s*,\\s*from", " from");
        processed = processed.replaceAll("\\s*,\\s*where", " where");
        processed = processed.replaceAll("\\s*,\\s*order", " order");
        // 去掉末尾的逗号
        processed = processed.replaceAll(",\\s*$", "");
        
        return processed;
    }

    /**
     * 处理include标签的替换
     */
    private String processIncludeTags(String sql) {
        if (sql == null || !sql.contains("<include")) {
            return sql;
        }
        
        String processed = sql;
        
        // 处理Base_Column_List的include
        while (processed.contains("<include refid=\"Base_Column_List\"")) {
            // 动态从缓存中获取Base_Column_List内容
            String baseColumnList = getBaseColumnListFromCache();
            
            int includeStart = processed.indexOf("<include refid=\"Base_Column_List\"");
            int includeEnd = processed.indexOf("/>", includeStart) + 2;
            
            if (includeEnd < 2) {
                // 没有找到结束标签，跳出循环避免无限循环
                break;
            }
            
            String beforeInclude = processed.substring(0, includeStart);
            String afterInclude = processed.substring(includeEnd);
            
            // 如果没有找到Base_Column_List内容，使用通用占位符
            if (baseColumnList.isEmpty()) {
                logger.debug("Base_Column_List为空，使用通用占位符");
                baseColumnList = "*";
            }
            
            // 更精确地检查前面是否有select字段
            boolean hasFieldsBeforeInclude = false;
            if (beforeInclude.toLowerCase().contains("select")) {
                String afterSelect = beforeInclude.substring(beforeInclude.toLowerCase().lastIndexOf("select") + 6);
                
                // 去掉所有空白字符和换行符，然后检查是否有内容
                String cleanAfterSelect = afterSelect.replaceAll("\\s+", " ").trim();
                
                // 如果select后面有内容，且不是单纯的from关键字，则认为有字段
                // 修复：要检查是否整个单词就是"from"，而不是仅仅以"from"开头
                if (!cleanAfterSelect.isEmpty()) {
                    // 检查是否整个字符串就是"from"（忽略大小写）
                    if (!"from".equalsIgnoreCase(cleanAfterSelect.trim())) {
                        hasFieldsBeforeInclude = true;
                    }
                }
            }
            
            if (hasFieldsBeforeInclude) {
                // 更精确地处理逗号添加
                String cleanedBefore = beforeInclude.replaceAll("\\s+", " ").trim();
                
                if (cleanedBefore.endsWith(",")) {
                    // 前面已经有逗号，直接添加空格和列名
                    processed = beforeInclude + " " + baseColumnList + afterInclude;
                } else {
                    // 前面没有逗号，需要添加逗号
                    // 保持原有的格式，在最后一个非空白字符后添加逗号
                    int lastNonWhitespaceIndex = -1;
                    for (int i = beforeInclude.length() - 1; i >= 0; i--) {
                        if (!Character.isWhitespace(beforeInclude.charAt(i))) {
                            lastNonWhitespaceIndex = i;
                            break;
                        }
                    }
                    
                    if (lastNonWhitespaceIndex >= 0) {
                        String beforeNonWhitespace = beforeInclude.substring(0, lastNonWhitespaceIndex + 1);
                        String whitespace = beforeInclude.substring(lastNonWhitespaceIndex + 1);
                        processed = beforeNonWhitespace + "," + whitespace + baseColumnList + afterInclude;
                    } else {
                        // 如果没有找到非空白字符，直接添加
                        processed = beforeInclude + baseColumnList + afterInclude;
                    }
                }
            } else {
                // 没有前面的字段，直接替换
                processed = beforeInclude + baseColumnList + afterInclude;
            }
        }
        
        // 处理其他where条件的include标签
        processed = processed.replaceAll("<include\\s+refid=\"[^\"]*Where[^\"]*\"\\s*/>", "1=1");
        
        // 处理其他未知的include标签
        processed = processed.replaceAll("<include\\s+refid=\"[^\"]*\"\\s*/>", "");
        
        return processed;
    }
    
    /**
     * 从缓存中获取Base_Column_List内容
     * 如果缓存中没有，则返回空字符串，不使用硬编码默认值
     */
    private String getBaseColumnListFromCache() {
        String baseColumnList = sqlFragmentCache.get("Base_Column_List");
        if (baseColumnList != null && !baseColumnList.trim().isEmpty()) {
            return baseColumnList.trim();
        }
        
        // 如果缓存中没有，返回空字符串，让调用方决定如何处理
        logger.debug("未找到Base_Column_List片段，返回空字符串");
        return "";
    }
    
    /**
     * 构建SQL片段缓存，从XML中提取sql标签定义的片段
     */
    private void buildSqlFragmentCache(org.dom4j.Element rootElement) {
        if (rootElement == null) {
            return;
        }
        
        // 提取所有的sql标签
        List<org.dom4j.Element> sqlElements = rootElement.elements("sql");
        for (org.dom4j.Element sqlElement : sqlElements) {
            String id = sqlElement.attributeValue("id");
            String content = sqlElement.getTextTrim();
            
            if (id != null && content != null) {
                sqlFragmentCache.put(id, content);
                logger.debug("缓存SQL片段: {} -> {}", id, content);
            }
        }
    }

    @Override
    public String buildSQLExtractionResponseWithOriginal(XMLParseResult parseResult, String fileIdentifier) {
        try {
            Map<String, Object> response = new HashMap<>();
            response.put("success", parseResult.isParseSuccess());
            response.put("fileName", fileIdentifier);
            response.put("namespace", parseResult.getNamespace());
            if (parseResult.isParseSuccess()) {
                List<java.util.Map<String, Object>> sqlList = new ArrayList<>();
                if (parseResult.getSqlLocations() != null) {
                    for (SQLLocation sqlLocation : parseResult.getSqlLocations()) {
                        Map<String, Object> sqlInfo = new HashMap<>();
                        // originalSql存储在xmlPath字段
                        String originalSql = sqlLocation.getXmlPath().startsWith("ORIGINAL:") ? sqlLocation.getXmlPath().substring(9) : sqlLocation.getSqlContent();
                        
                        // 修复SQL，使其成为标准SQL
                        String fixedSql = fixMybatisSqlToStandardSql(originalSql, sqlLocation.getElementType());
                        
                        // 如果返回null，表示跳过此SQL的解析
                        if (fixedSql == null) {
                            continue;
                        }
                        
                        sqlInfo.put("originalSql", originalSql);
                        sqlInfo.put("fixedSql", fixedSql);
                        sqlInfo.put("sqlId", sqlLocation.getSqlId());
                        sqlInfo.put("sqlType", sqlLocation.getSqlType() != null ? sqlLocation.getSqlType().name() : "UNKNOWN");
                        sqlInfo.put("elementType", sqlLocation.getElementType());
                        sqlInfo.put("startLine", sqlLocation.getStartLine());
                        sqlInfo.put("endLine", sqlLocation.getEndLine());
                        boolean isComplete = isSQLComplete(fixedSql);
                        sqlInfo.put("isComplete", isComplete);
                        if (!isComplete) {
                            sqlInfo.put("warning", "SQL语句可能不完整，请检查是否包含动态标签或引用了sql片段");
                        }
                        sqlList.add(sqlInfo);
                    }
                }
                response.put("sqlCount", sqlList.size());
                response.put("sqlStatements", sqlList);
                long completeCount = sqlList.stream().mapToLong(sql -> Boolean.TRUE.equals(sql.get("isComplete")) ? 1 : 0).sum();
                response.put("completeCount", completeCount);
                response.put("incompleteCount", sqlList.size() - completeCount);
            } else {
                response.put("errorMessage", parseResult.getErrorMessage());
                response.put("sqlCount", 0);
                response.put("sqlStatements", new java.util.ArrayList<>());
            }
            response.put("timestamp", LocalDateTime.now().toString());
            return objectMapper.writeValueAsString(response);
        } catch (JsonProcessingException e) {
            logger.error("构建SQL提取响应失败: {}", e.getMessage(), e);
            return formatErrorResponse("构建响应失败: " + e.getMessage());
        }
    }
    
    /**
     * 格式化错误响应
     */
    private String formatErrorResponse(String errorMessage) {
        try {
            return objectMapper.writeValueAsString(new java.util.HashMap<String, Object>() {{
                put("success", false);
                put("error", errorMessage);
                put("timestamp", LocalDateTime.now().toString());
            }});
        } catch (JsonProcessingException e) {
            logger.error("格式化错误响应失败: {}", e.getMessage());
            return "{\"success\": false, \"error\": \"" + errorMessage + "\"}";
        }
    }

    @Override
    public XMLParseResult robustParseXmlContent(String xmlContent, String fileIdentifier) {
        XMLParseResult bestResult = null;
        int maxSqlCount = 0;
        
        // 优先策略：正则表达式提取SQL（保留完整的MyBatis动态标签）
        logger.info("优先使用正则表达式提取SQL以保留动态标签: {}", fileIdentifier);
        XMLParseResult regexResult = extractSqlByRegex(xmlContent, fileIdentifier);
        if (regexResult.getSqlLocations() != null) {
            bestResult = regexResult;
            maxSqlCount = regexResult.getSqlLocations().size();
            logger.info("正则表达式提取成功，保留完整内容: {}, SQL数量: {}", fileIdentifier, maxSqlCount);
        }
        
        // 策略1：直接解析原始内容
        XMLParseResult result = tryParseXmlContent(xmlContent, fileIdentifier, "原始内容");
        if (result.isParseSuccess() && result.getSqlLocations() != null) {
            int sqlCount = result.getSqlLocations().size();
            if (sqlCount > maxSqlCount) {
                bestResult = result;
                maxSqlCount = sqlCount;
                logger.info("DOM解析提取到更多SQL，切换到DOM解析结果: {}", fileIdentifier);
            }
        }
        
        // 策略2：清理常见问题字符后解析
                    String cleanedContent = cleanInvalidXmlCharacters(xmlContent);
        result = tryParseXmlContent(cleanedContent, fileIdentifier, "清理后内容");
        if (result.isParseSuccess() && result.getSqlLocations() != null) {
            int sqlCount = result.getSqlLocations().size();
            if (sqlCount > maxSqlCount) {
                bestResult = result;
                maxSqlCount = sqlCount;
                logger.info("清理后解析提取到更多SQL: {}", fileIdentifier);
            }
        }
        
        // 策略3：修复常见XML结构问题后解析
                    String fixedContent = tryFixXmlContent(cleanedContent);
        result = tryParseXmlContent(fixedContent, fileIdentifier, "修复后内容");
        if (result.isParseSuccess() && result.getSqlLocations() != null) {
            int sqlCount = result.getSqlLocations().size();
            if (sqlCount > maxSqlCount) {
                bestResult = result;
                maxSqlCount = sqlCount;
                logger.info("修复后解析提取到更多SQL: {}", fileIdentifier);
            }
        }
        
        logger.info("XML解析完成，最佳策略提取到 {} 个SQL: {}", maxSqlCount, fileIdentifier);
        return bestResult != null ? bestResult : regexResult;
    }
    
    @Override
    public String extractSQLsFromXML(String xmlFilePath) {
        long startTime = System.currentTimeMillis();

        try {
            // 验证文件路径
            if (xmlFilePath == null || xmlFilePath.trim().isEmpty()) {
                return formatErrorResponse("必须提供有效的XML文件路径");
            }

            // 读取XML文件内容
            String xmlContent = readXmlFileContent(xmlFilePath);
            if (xmlContent == null) {
                return formatErrorResponse("无法读取XML文件：" + xmlFilePath);
            }

            // 提取文件名用于日志标识
            String fileName = extractFileNameFromPath(xmlFilePath);
            logger.info("开始从XML文件提取SQL语句: {}", fileName);

            // 预处理XML内容：去除不需要的标签
            xmlContent = preprocessXmlContent(xmlContent);

            // 使用增强的XML解析逻辑，传入原始未预处理的XML内容进行正则表达式提取
            XMLParseResult parseResult = robustParseXmlContent(xmlContent, fileName);

            // 如果使用的是正则表达式提取的结果，尝试用原始XML重新提取以保留更多动态标签
            if (parseResult != null && parseResult.getSqlLocations() != null) {
                String originalXmlForRegex = readXmlFileContent(xmlFilePath);
                if (originalXmlForRegex != null) {
                    XMLParseResult regexResult = extractSqlByRegex(originalXmlForRegex, fileName);
                    if (regexResult.getSqlLocations() != null && regexResult.getSqlLocations().size() >= parseResult.getSqlLocations().size()) {
                        // 如果正则表达式提取到的SQL数量不少于当前结果，则使用正则表达式结果
                        parseResult = regexResult;
                        logger.info("使用原始XML内容进行正则表达式提取，保留更完整的动态标签: {}", fileName);
                    }
                }
            }

            // 对每条SQL进行自动修复，确保为标准SQL
            if (parseResult.getSqlLocations() != null && !parseResult.getSqlLocations().isEmpty()) {
                logger.info("=== 开始处理提取的SQL语句 ===");
                int originalSqlCount = parseResult.getSqlLocations().size();
                logger.info("文件: {}, 总SQL数量: {}", fileName, originalSqlCount);
                
                List<SQLLocation> validSqlLocations = new ArrayList<>();
                for (SQLLocation sqlLocation : parseResult.getSqlLocations()) {
                    String originalSql = sqlLocation.getSqlContent();
                    String fixedSql = fixMybatisSqlToStandardSql(originalSql, sqlLocation.getElementType());

                    // 如果修复后的SQL为null，跳过此SQL
                    if (fixedSql == null) {
                        logger.info("跳过复杂嵌套SQL: {}", sqlLocation.getSqlId());
                        continue;
                    }

                    // 移除selectKey标签后记录原始SQL
                    String originalSqlWithoutSelectKey = originalSql.replaceAll("(?s)<selectKey[^>]*>.*?</selectKey>", "");
                    sqlLocation.setXmlPath("ORIGINAL:" + originalSqlWithoutSelectKey);
                    // 设置修复后的SQL
                    sqlLocation.setSqlContent(fixedSql);
                    validSqlLocations.add(sqlLocation);

                    // 详细的日志输出
                    logger.info("=== SQL #{} 处理详情 ===", sqlLocation.getSqlId());
                    logger.info("类型: {}", sqlLocation.getElementType());
                    logger.info("SQL类型: {}", sqlLocation.getSqlType());
                    logger.info("原始SQL (完整):\n{}", originalSql);
                    logger.info("修复后SQL (完整):\n{}", fixedSql);
                    logger.info("原始SQL长度: {}, 修复后SQL长度: {}", originalSql.length(), fixedSql != null ? fixedSql.length() : 0);
                    logger.info("=== SQL #{} 处理完成 ===\n", sqlLocation.getSqlId());
                }
                
                // 更新parseResult中的sqlLocations为过滤后的有效SQL列表
                parseResult.setSqlLocations(validSqlLocations);
                
                logger.info("=== 所有SQL处理完成 ===");
                logger.info("有效SQL数量: {}, 跳过SQL数量: {}", validSqlLocations.size(), 
                        originalSqlCount - validSqlLocations.size());
            }

            String result = buildSQLExtractionResponseWithOriginal(parseResult, fileName);
            long duration = System.currentTimeMillis() - startTime;
            logger.info("SQL提取并修复完成: {}, SQL数量: {}, 耗时: {}ms",
                    fileName,
                    parseResult.getSqlLocations() != null ? parseResult.getSqlLocations().size() : 0,
                    duration);
            return result;

        } catch (Exception e) {
            long errorTime = System.currentTimeMillis() - startTime;
            logger.error("SQL提取失败: {}, 耗时: {}ms, 错误: {}", xmlFilePath, errorTime, e.getMessage(), e);
            return formatErrorResponse("SQL提取失败: " + e.getMessage());
        }
    }
    
    /**
     * 尝试解析XML内容
     */
    private XMLParseResult tryParseXmlContent(String xmlContent, String fileIdentifier, String strategy) {
        try {
            logger.debug("尝试解析XML - 策略: {}, 文件: {}", strategy, fileIdentifier);
            XMLParseResult result = parseFileContent(xmlContent, fileIdentifier);
            if (result.isParseSuccess()) {
                logger.info("XML解析成功 - 策略: {}, 文件: {}, SQL数量: {}", strategy, fileIdentifier, 
                        result.getSqlLocations() != null ? result.getSqlLocations().size() : 0);
            }
            return result;
        } catch (Exception e) {
            logger.debug("XML解析失败 - 策略: {}, 文件: {}, 错误: {}", strategy, fileIdentifier, e.getMessage());
            XMLParseResult errorResult = XMLParseResult.forMyBatis(fileIdentifier);
            errorResult.setXmlPath(fileIdentifier);
            errorResult.setParseSuccess(false);
            errorResult.setErrorMessage("解析失败: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 使用正则表达式提取SQL语句（备用方案）
     * 此方法会完整保留MyBatis动态标签、include引用和所有特殊函数
     */
    private XMLParseResult extractSqlByRegex(String xmlContent, String fileIdentifier) {
        XMLParseResult result = XMLParseResult.forMyBatis(fileIdentifier);
        result.setXmlPath(fileIdentifier);
        result.setParseSuccess(true);
        
        List<SQLLocation> sqlLocations = new ArrayList<>();
        
        try {
            // 提取namespace
            Pattern namespacePattern = Pattern.compile("namespace\\s*=\\s*[\"']([^\"']+)[\"']");
            Matcher namespaceMatcher = namespacePattern.matcher(xmlContent);
            if (namespaceMatcher.find()) {
                result.setNamespace(namespaceMatcher.group(1));
            }
            
            // 根据格式选择不同的SQL标签
            String[] sqlTags = new String[]{"select", "insert", "update", "delete"};
            logger.info("检测到MyBatis格式XML文件: {}", fileIdentifier);

            // 提取SQL语句
            for (String tag : sqlTags) {
                // 改进的正则表达式，使用更健壮的匹配策略处理复杂嵌套标签
                // 首先尝试标准匹配
                Pattern standardPattern = Pattern.compile(
                    "<" + tag + "\\s+[^>]*id\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)</" + tag + ">",
                    Pattern.CASE_INSENSITIVE | Pattern.DOTALL
                );
                
                // 备用匹配模式，处理可能包含CDATA或注释的情况
                Pattern robustPattern = Pattern.compile(
                    "<" + tag + "\\s+[^>]*id\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)</" + tag + "\\s*>",
                    Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE
                );
                
                // 先使用标准模式匹配
                Matcher matcher = standardPattern.matcher(xmlContent);
                Set<String> processedIds = new HashSet<>();
                
                while (matcher.find()) {
                    String sqlId = matcher.group(1);
                    String sqlContent = matcher.group(2);
                    
                    if (sqlContent != null && !processedIds.contains(sqlId)) {
                        processedIds.add(sqlId);
                        SQLLocation location = createSqlLocationFromContent(sqlId, sqlContent, tag, fileIdentifier);
                        if (location != null) {
                            sqlLocations.add(location);
                            logger.debug("标准模式提取SQL: {} - {}", sqlId, tag);
                        }
                    }
                }
                
                // 如果标准模式没有匹配到足够的SQL，使用健壮模式重新匹配
                matcher = robustPattern.matcher(xmlContent);
                while (matcher.find()) {
                    String sqlId = matcher.group(1);
                    String sqlContent = matcher.group(2);
                    
                    if (sqlContent != null && !processedIds.contains(sqlId)) {
                        processedIds.add(sqlId);
                        SQLLocation location = createSqlLocationFromContent(sqlId, sqlContent, tag, fileIdentifier);
                        if (location != null) {
                            sqlLocations.add(location);
                            logger.debug("健壮模式提取SQL: {} - {}", sqlId, tag);
                        }
                    }
                }
            }
            
            // 处理sql片段标签
            Pattern sqlFragmentPattern = Pattern.compile(
                "<sql\\s+[^>]*id\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)</sql>",
                Pattern.CASE_INSENSITIVE | Pattern.DOTALL
            );
            Matcher sqlFragmentMatcher = sqlFragmentPattern.matcher(xmlContent);
            while (sqlFragmentMatcher.find()) {
                String sqlId = sqlFragmentMatcher.group(1);
                String sqlContent = sqlFragmentMatcher.group(2);
                
                if (sqlContent != null) {
                    SQLLocation location = createSqlLocationFromContent(sqlId, sqlContent, "sql", fileIdentifier);
                    if (location != null) {
                        sqlLocations.add(location);
                        logger.debug("提取SQL片段: {} - sql", sqlId);
                    }
                }
            }
            
            result.setSqlLocations(sqlLocations);
            logger.info("正则表达式提取完成: {}, 总SQL数量: {}", fileIdentifier, sqlLocations.size());
            
        } catch (Exception e) {
            logger.error("正则表达式提取SQL时发生错误: {}", fileIdentifier, e);
            result.setParseSuccess(false);
            result.setErrorMessage("正则表达式提取失败: " + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 从SQL内容创建SQLLocation对象
     */
    private SQLLocation createSqlLocationFromContent(String sqlId, String sqlContent, String elementType, String fileIdentifier) {
        try {
            if (sqlContent == null || sqlContent.trim().isEmpty()) {
                return null;
            }
            
            SQLLocation location = new SQLLocation();
            location.setXmlPath(fileIdentifier);
            location.setSqlId(sqlId);
            
            // 首先移除selectKey标签
            String contentWithoutSelectKey = sqlContent.replaceAll("(?s)<selectKey[^>]*>.*?</selectKey>", "");
            
            // 保留完整的原始SQL内容，包括所有MyBatis标签和函数
            String preservedContent = preserveCompleteContent(contentWithoutSelectKey);
            location.setSqlContent(preservedContent);
            location.setElementType(elementType);
            location.setSqlType(getSQLType(elementType));
            
            // 检查SQL完整性（仅用于日志记录）
            boolean isComplete = isSQLComplete(preservedContent);
            if (!isComplete) {
                logger.debug("SQL语句可能不完整: {}", sqlId);
            }
            
            // 记录原始SQL内容用于调试
            logger.debug("提取到{}语句: {}, 原始内容长度: {}, 处理后长度: {}", 
                    elementType, sqlId, sqlContent.length(), preservedContent.length());
            
            return location;
            
        } catch (Exception e) {
            logger.error("创建SQLLocation失败: {}, SQL ID: {}", fileIdentifier, sqlId, e);
            return null;
        }
    }
    
    /**
     * 保留完整的SQL内容，包括MyBatis动态标签、函数等
     */
    private String preserveCompleteContent(String sqlContent) {
        if (sqlContent == null) {
            return "";
        }
        
        String preserved = sqlContent;
        
        // 保留XML转义字符的正确处理
        preserved = preserved.replaceAll("&lt;", "<");
        preserved = preserved.replaceAll("&gt;", ">");
        preserved = preserved.replaceAll("&amp;", "&");
        
        // 完全保留原始格式，只清理首尾空白
        return preserved.trim();
    }
    
    @Override
    public List<String> scanXmlFiles(String directoryPath, boolean recursive) {
        List<String> xmlFiles = new ArrayList<>();
        
        try {
            Path dirPath = Paths.get(directoryPath);
            if (!Files.exists(dirPath)) {
                logger.error("目录不存在: {}", directoryPath);
                return xmlFiles;
            }
            
            if (!Files.isDirectory(dirPath)) {
                logger.error("指定路径不是目录: {}", directoryPath);
                return xmlFiles;
            }
            
            scanDirectory(dirPath, xmlFiles, recursive);
            
            logger.info("扫描XML文件完成，目录: {}, 递归: {}, 找到文件数: {}", 
                    directoryPath, recursive, xmlFiles.size());
                    
        } catch (Exception e) {
            logger.error("扫描目录失败: {}", directoryPath, e);
        }
        
        return xmlFiles;
    }

    @Override
    public String buildDirectoryAnalysisErrorResponse(String directoryPath, boolean recursive, long startTime, String errorMessage) {
        try {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("directoryPath", directoryPath);
            response.put("recursive", recursive);
            response.put("error", errorMessage);
            response.put("timestamp", LocalDateTime.now().toString());
            response.put("analyzeDuration", System.currentTimeMillis() - startTime);

            return objectMapper.writeValueAsString(response);
        } catch (Exception e) {
            return String.format("{\"success\": false, \"error\": \"构建错误响应失败\", \"directoryPath\": \"%s\", \"details\": \"%s\", \"timestamp\": \"%s\"}",
                    directoryPath, e.getMessage(), LocalDateTime.now());
        }
    }

    /**
     * 递归扫描目录，查找XML文件
     */
    private void scanDirectory(Path dirPath, List<String> xmlFiles, boolean recursive) {
        try {
            Files.list(dirPath).forEach(path -> {
                if (Files.isDirectory(path) && recursive) {
                    // 递归扫描子目录
                    scanDirectory(path, xmlFiles, recursive);
                } else if (Files.isRegularFile(path) && isXmlFile(path)) {
                    // 添加XML文件
                    xmlFiles.add(path.toString());
                }
            });
        } catch (Exception e) {
            logger.error("扫描目录失败: {}", dirPath, e);
        }
    }
    
    /**
     * 判断是否为XML文件
     */
    private boolean isXmlFile(Path path) {
        String fileName = path.getFileName().toString().toLowerCase();
        return fileName.endsWith(".xml");
    }
    
    /**
     * 替换SQL中的参数（#参数名#）为空字符串
     */
    private String replaceParametersWithEmptyString(String sql) {
        if (sql == null) {
            return "";
        }
        
        String processed = sql;
        // 替换 #{参数名,jdbcType=XXX} 为空字符串 - 支持包含逗号的完整参数
        processed = processed.replaceAll("#\\{[^}]*\\}", "''");
        // 替换 ${参数名} 为空字符串
        processed = processed.replaceAll("\\$\\{[^}]*\\}", "''");
        // 兼容旧格式：替换 #参数名# 为空字符串
        processed = processed.replaceAll("#[^#]*#", "''");
        // 兼容旧格式：替换 $参数名$ 为空字符串
        processed = processed.replaceAll("\\$[^$]*\\$", "''");
        
        return processed;
    }
    
    /**
     * 处理函数中的变量替换（to_char, DATE_FORMAT等）
     */
    private String replaceFunctionVariables(String sql) {
        if (sql == null || sql.trim().isEmpty()) {
            return sql;
        }
        
        String processed = sql;
        
        // 处理 to_char(变量, 格式) -> to_char('', 格式)
        processed = processed.replaceAll(
            "(?i)to_char\\s*\\(\\s*[a-zA-Z_][a-zA-Z0-9_.]*\\s*,",
            "to_char('',"
        );
        
        // 处理 DATE_FORMAT(变量, 格式) -> DATE_FORMAT('', 格式)
        processed = processed.replaceAll(
            "(?i)DATE_FORMAT\\s*\\(\\s*[a-zA-Z_][a-zA-Z0-9_.]*\\s*,",
            "DATE_FORMAT('',"
        );
        
        return processed;
    }
 }